2013-12-17 66 views
12

我知道這個問題已經在這裏被詢問和回答了很多次。但是我第一次處理這件事,仍然無法在腦海中完美實現它。這裏的代碼我有我實現的代理方法將SecondViewController的數據傳遞給FirstViewController使用委託和協議在2個UIViewController之間傳遞數據

FirstViewController.h

#import "SecondViewController.h" 

@interface FirstViewController : UITableViewController<sampleDelegate> 
@end 

FirstViewController.m

@interface FirstViewController() 

// Array in which I want to store the data I get back from SecondViewController. 
@property (nonatomic, copy) NSArray *sampleData; 
@end 

@implementation FirstViewController 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SecondViewController *controller = [[SecondViewController alloc] init];   
    [self.navigationController pushViewController:controller animated:YES]; 
} 
@end 

SecondViewController.h

@protocol sampleDelegate <NSObject> 
- (NSArray*)sendDataBackToFirstController; 
@end 

@interface SecondViewController : UITableViewController 
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; 
@end 

SecondViewController.m

@interface SecondViewController() 
@property (strong, nonatomic) NSArray *dataInSecondViewController; 
@end 

@implementation SecondViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil]; 
} 

- (NSArray*)sendDataBackToFirstController 
{ 
    return self.dataInSecondViewController; 
} 
@end 

我是不是做正確嗎?我希望它將self.dataInSecondViewController中的數據發送到FirstViewController,並將其保存在NSArray屬性sampleDataFirstViewController之上。

不知何故,我無法訪問FirstViewController中的sendDataBackToFirstController。還有什麼其他的東西想要在那裏訪問sendDataBackToFirstController

+1

您需要設置第一個VC爲代表第二個vc。所以第二個vc的委託方法需要在第一個vc中實現。然後在觸發事件時從第二個vc調用該方法。從你的情況來看,如果你想擁有一個數據源或代表,你就不清楚了。如果使用第二個vc作爲第一個vc的數據源,則它是第一個請求數據的vc。但是,當第二個vc發生某種事件時,它只是想返回第一個vc,然後是它的委託類型。然後,您需要將返回類型更改爲void並將數據作爲參數傳遞。 – Anupdas

+0

正確。我試着在我的First vc的didSelectRow中做controller.delegate = self。但不知何故,控制器無法找到委託對象。我的代碼到目前爲止看起來是否正確? –

+0

請按照@gdavis和藝術的答案 – Anupdas

回答

8

不完全正確。首先,您需要在第一個視圖控制器中分配委託屬性,以便第二個視圖控制器知道將消息發送到哪個對象。

FirstViewController.m

controller.delegate = self; 

其次,你必須在發送和接收向後的委託方法。您可以通過FirstViewController在第二個控制器上調用sendDataBackToFirstController的方式進行設置。在委託模式中,SecondViewController是發送消息並可選擇使用該方法發送數據的模式。所以,你應該將委託聲明更改爲類似這樣:

@protocol sampleDelegate <NSObject> 
- (void)secondControllerFinishedWithItems:(NSArray*)newData; 
@end 

然後,當你SecondViewController完成其任務,需要通知其委託,就應該做這樣的事情:

// ... do a bunch of tasks ... 
// notify delegate 
if ([self.delegate respondsToSelector:@selector(secondControllerFinishedWithItems:)]) { 
    [self.delegate secondControllerFinishedWithItems:arrayOfNewData]; 
} 

我在這裏添加一個額外的if語句來檢查以確保委託在實際發送之前會響應我們想要發送的方法。如果我們的協議中有可選的方法,並且沒有這個方法,那麼應用程序會崩潰。

希望這會有所幫助!

+0

您和@藝術的解釋幫助我理解了協議和代表的整個流程。我遵循你的和藝術的代碼來實現代表,我得到了我想要的。我將委託屬性更改爲弱而不是強壯以防止保留週期。 –

1

首先改變 @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;@property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject;防止保留週期搜索谷歌與詞的解釋。

二 的協議應該是

@protocol sampleDelegate <NSObject> 
- (void)sendDataBackToFirstController:(NSArray*)dataToSendBack; 
@end 

,當你想將數據發送回調用[self.sampleDelegateObject sendDataBackToFirstControoler:yourData];第一視圖控制器必須實現協議的方法。

4

請點擊此

FirstViewController.h

#import "SecondViewController.h" 

    @interface FirstViewController : UITableViewController<sampleDelegate> 
    @end 

FirstViewController.m

@interface FirstViewController() 

    // Array in which I want to store the data I get back from SecondViewController. 
    @property (nonatomic, copy) NSArray *sampleData; 
    @end 

@implementation FirstViewController 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    SecondViewController *controller = [[SecondViewController alloc] init]; 
    controller.sampleDelegateObject=self;  
    [self.navigationController pushViewController:controller animated:YES]; 

} 

    //implementation of delegate method 
    - (NSArray*)sendDataBackToFirstController 
{ 
    return self.dataInSecondViewController; 
} 
@end 

SecondViewController.h

@protocol sampleDelegate <NSObject> 
- (NSArray*)sendDataBackToFirstController; 
@end 

@interface SecondViewController : UITableViewController 
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; 
@end 
SecondViewController.m 

@interface SecondViewController() 
@property (strong, nonatomic) NSArray *dataInSecondViewController; 
@end 

@implementation SecondViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil]; 
    //calling the delegate method 
    [sampleDelegateObject sendDataBackToFirstController]; 
} 


    @end 
+1

協議的實現將在您想要實現的類中 –

+0

感謝您使用代碼的詳細信息。 –