dismissModalViewController并传回数据

我有两个视图控制器, firstViewControllersecondViewController 。 我正在使用这个代码切换到我的secondViewController(我也传递一个string):

secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil]; second.myString = @"This text is passed from firstViewController!"; second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:second animated:YES]; [second release]; 

然后我在secondViewController中使用这个代码切换回firstViewController:

 [self dismissModalViewControllerAnimated:YES]; 

所有这一切正常。 我的问题是,如何将数据传递给firstViewController? 我想从secondViewController传入一个不同的string到firstViewController。

我感谢任何帮助。 多谢你们。

你需要使用委托协议…下面是如何做到这一点:

在你的secondViewController的头文件中声明一个协议。 它应该是这样的:

 #import <UIKit/UIKit.h> @protocol SecondDelegate <NSObject> -(void)secondViewControllerDismissed:(NSString *)stringForFirst @end @interface SecondViewController : UIViewController { id myDelegate; } @property (nonatomic, assign) id<SecondDelegate> myDelegate; 

不要忘记综合你的实现(SecondViewController.m)文件中的myDelegate:

 @synthesize myDelegate; 

在您的FirstViewController的头文件中,通过执行此操作订阅SecondDelegate协议:

 #import "SecondViewController.h" @interface FirstViewController:UIViewController <SecondDelegate> 

现在,当您在FirstViewController中实例化SecondViewController时,您应该执行以下操作:

 // If you're using a view controller built with Interface Builder. SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]]; // If you're using a view controller built programmatically. SecondViewController *second = [SecondViewController new]; // Convenience initializer that uses alloc] init] second.myString = @"This text is passed from firstViewController!"; second.myDelegate = self; second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; [self presentModalViewController:second animated:YES]; [second release]; 

最后,在你的第一个视图控制器(FirstViewController.m)的实现文件中,为secondViewControllerDismissed实现SecondDelegate的方法:

 - (void)secondViewControllerDismissed:(NSString *)stringForFirst { NSString *thisIsTheDesiredString = stringForFirst; //And there you have it..... } 

现在,当您要closures第二个视图控制器时,您需要调用在第一个视图控制器中实现的方法。 这部分很简单。 你所做的只是在你的第二个视图控制器中,在解除代码之前添加一些代码:

 if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)]) { [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"]; } [self dismissModalViewControllerAnimated:YES]; 

代表协议是极其有用的,特别有用。 这将是你很好熟悉它们:)

NSNotifications是另一种方式来做到这一点,但作为一个最佳实践,我希望在多个viewController或对象之间进行通信时使用它。 这是我之前发布的一个答案,如果你对使用NSNotifications感兴趣: 从appdelegate中的线程触发多个视图控制器的事件

编辑:

如果你想传递多个参数,那么解除前的代码如下所示:

 if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)]) { [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject]; } [self dismissModalViewControllerAnimated:YES]; 

这意味着您的firstViewController中的SecondDelegate方法实现将如下所示:

 - (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2 { NSString thisIsTheDesiredString = stringForFirst; NSObject desiredObject1 = inObject1; //....and so on } 

我可能不在这里,但我开始更喜欢块语法的非常详细的委托/协议的方法。 如果你从vc1创buildvc2,在vc2上有一个属性,你可以从vc1中设置一个块!

 @property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response); 

然后,当vc2中发生了一些你想告诉vc1的事情时,只需执行你在vc1中定义的块!

 self.somethingHappenedInVC2(@"Hello!"); 

这使您可以将数据从vc2发回到vc1。 就像魔术一样。 海事组织,这比协议更容易/更清洁。 块是真棒,需要尽可能地拥抱。

编辑 – 改进的例子

比方说,我们有一个主要的VC,我们想暂时提交一个模态VC来获得用户的一些input。 为了从mainVC中呈现modalVC,我们需要在mainVC中分配/ init它。 很基本的东西。 那么当我们做这个modalVC对象的时候,我们也可以在它上面设置一个block属性,使我们可以很容易地在两个vc对象之间进行通信。 所以让我们从上面的例子中,把follwing属性放在modalVC的.h文件中:

  @property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response); 

然后,在我们的mainVC中,在alloc / init了一个新的modalVC对象后,设置modalVC的block属性如下:

 ModalVC *modalVC = [[ModalVC alloc] init]; modalVC.somethingHappenedInModalVC = ^(NSString *response) { NSLog(@"Something was selected in the modalVC, and this is what it was:%@", response); } 

所以我们只是设置块的属性,并定义执行该块时会发生什么。

最后,在我们的modalVC中,我们可以有一个由dataSource数组的string支持的tableViewController。 一旦select行,我们可以做这样的事情:

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedString = self.dataSource[indexPath.row]; self.somethingHappenedInModalVC(selectedString); } 

当然,每当我们在modalVC中select一行时,我们将从mainVC中获取NSLog行的控制台输出。 希望有所帮助!

嗯,寻找通知中心,并在通知中传回信息。 这里是苹果承担 – 我个人采取这种方法,除非任何人有任何其他的build议

在第二个视图控制器中定义委托协议,并将第一个委托给第二个委托。