首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >dismissModalViewController并将数据传回

dismissModalViewController并将数据传回
EN

Stack Overflow用户
提问于 2011-06-01 23:34:19
回答 4查看 34.4K关注 0票数 83

我有两个视图控制器,firstViewControllersecondViewController.我使用下面的代码切换到我的secondViewController (我还向它传递了一个字符串):

代码语言:javascript
复制
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:

代码语言:javascript
复制
[self dismissModalViewControllerAnimated:YES];

所有这些都运行得很好。我的问题是,我如何将数据传递给firstViewController?我想从secondViewController向firstViewController传递一个不同的字符串。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-02 00:19:01

你需要使用委托协议..。下面是如何做的:

在您的第二个secondViewController的头文件中声明一个协议。它应该看起来像这样:

代码语言:javascript
复制
#import <UIKit/UIKit.h>

@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end


@interface SecondViewController : UIViewController
{
    id myDelegate;  
}

@property (nonatomic, assign) id<SecondDelegate>    myDelegate;

别忘了在你的实现(secudViewController.m)文件中合成myDelegate:

代码语言:javascript
复制
@synthesize myDelegate;

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

代码语言:javascript
复制
#import "SecondViewController.h"

@interface FirstViewController:UIViewController <SecondDelegate>

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

代码语言:javascript
复制
// 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实现method的方法:

代码语言:javascript
复制
- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
    NSString *thisIsTheDesiredString = stringForFirst; //And there you have it.....
}

现在,当您要关闭第二个视图控制器时,您希望调用在第一个视图控制器中实现的方法。这部分很简单。您所要做的就是,在第二个视图控制器中,在消除代码之前添加一些代码:

代码语言:javascript
复制
if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
    [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];

委托协议非常、非常、非常有用。熟悉它们会对您有好处:)

NSNotifications是实现此目的的另一种方法,但作为最佳实践,当我想跨多个viewControllers或对象进行通信时,我更喜欢使用它。如果你对使用NSNotifications感兴趣,这里有一个我之前发布的答案:Firing events accross multiple viewcontrollers from a thread in the appdelegate

编辑:

如果你想要传递多个参数,dismiss之前的代码如下所示:

代码语言:javascript
复制
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方法实现现在将如下所示:

代码语言:javascript
复制
- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
    NSString thisIsTheDesiredString = stringForFirst;
    NSObject desiredObject1 = inObject1;
    //....and so on
}
票数 141
EN

Stack Overflow用户

发布于 2013-11-09 03:46:26

我可能与这里格格不入,但我开始更喜欢块语法而不是非常冗长的委托/协议方法。如果你从vc1生成vc2,在vc2上有一个你可以从vc1设置的属性,那就是一个块!

代码语言:javascript
复制
@property (nonatomic, copy) void (^somethingHappenedInVC2)(NSString *response);

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

代码语言:javascript
复制
self.somethingHappenedInVC2(@"Hello!");

这允许您将数据从vc2发送回vc1。就像魔法一样。IMO,这比协议要简单/干净得多。块是很棒的,需要尽可能多地接受。

编辑-改进的示例

假设我们有一个mainVC,我们想在它上面临时显示一个modalVC,以便从用户那里获得一些输入。为了显示来自mainVC的modalVC,我们需要在mainVC中分配/初始化它。很基本的东西。当我们创建这个modalVC对象时,我们还可以在它上面设置一个块属性,这样我们就可以方便地在两个vc对象之间进行通信。因此,让我们以上面的示例为例,将以下属性放入modalVC的.h文件中:

代码语言:javascript
复制
 @property (nonatomic, copy) void (^somethingHappenedInModalVC)(NSString *response);  

然后,在我们的块中,在分配/初始化一个新的modalVC对象后,您可以像这样设置modalVC的mainVC属性:

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

因此,我们只需设置block属性,并定义当执行该块时会发生什么。

最后,在我们的modalVC中,我们可以有一个由dataSource字符串数组支持的tableViewController。一旦进行了行选择,我们就可以这样做:

代码语言:javascript
复制
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      NSString *selectedString = self.dataSource[indexPath.row];
      self.somethingHappenedInModalVC(selectedString);
 }

当然,每次我们在modalVC中选择一行,我们都会从mainVC中的NSLog行获得一个控制台输出。希望这能有所帮助!

票数 40
EN

Stack Overflow用户

发布于 2011-06-01 23:48:13

嗯,查找通知中心,并在通知中传回信息。here is apples take on it -我个人采用这种方法,除非任何人有任何其他建议

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6203799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档