2013-12-17 72 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

感谢您使用代码的详细信息。 –