dismissModalViewController并传回数据
我有两个视图控制器, firstViewController和secondViewController 。 我正在使用这个代码切换到我的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议
在第二个视图控制器中定义委托协议,并将第一个委托给第二个委托。
- iOS 7风格模糊视图
- 在故事板-IB中向原型单元添加项目时出现奇怪的错误
- RTCReporting&pancake.apple.com错误
- 架构i386的未定义符号:_OBJC_CLASS _ $ _ SKPSMTPMessage“,引用来自:错误
- 在iPhone应用程序如何检测设备的屏幕分辨率
- iOS 8从iTunesConnect中删除构build
- 如何正确地设置imageView中像imageContacts在Swift中?
- didRegisterForRemoteNotificationsWithDeviceToken不在ios8中调用,但didRegister …设置是
- parsingHTML到NSAttributedText – 如何设置字体?