iOS 6 - 我可以在取消 segue 时返回数据吗?

25

我使用故事板工具创建了一个简单的反向过渡。在我想要反转到的视图中,我创建了以下事件处理程序:

-(IBAction)quitQuiz:(UIStoryboardSegue *)segue {
    NSLog(@"SEGUE unwind");
}

这个代码可以正确执行并完成segue (消息被记录下来)。

当用户退出问答游戏时,我想传递一些数据,但一直无法实现。有人能提供建议吗?


嗨,你解决了吗?我也在寻找解决方案。谢谢。 - dan
1
Jeff的答案就是解决方案。在您的取消方法中使用YourViewController *yourVC = [segue sourceViewController];,然后您可以访问该VC对象上的插座/字段。 - Voicu
1
它能正常工作,但遗憾的是唯一的取消处理程序机制(目标“UIViewController”)获取来自取消启动器的信息的方式是通过被取消的“UIViewController”的公共接口。如果“UIStoryboardSegue”也提供了一种知道启动取消的“sender”的方式将更好。我认为在许多情况下,这可能是向取消处理程序提供信息的更好方法。 - Benjohn
6个回答

35

谢谢Jeff。在观看了WWDC视频407之后,我有了一个清晰的解决方案。

在作为反向传递目标的视图控制器中,您应该创建一个接受单个UIStoryboardSegue参数并返回IBAction的方法。UIStoryboardSegue有一个方法可以返回源视图控制器!以下是从视频中提取的示例(由Apple提供)。

- (IBAction)done:(UIStoryboardSegue *)segue {
    ConfirmationViewController *cc = [segue sourceViewController];
    [self setAccountInfo:[cc accountInfo]];
    [self setShowingSuccessView:YES];
}

不错的代码,只是为了澄清:ConfirmationViewController是我们从中解开的视图控制器,并且此方法存在于我们想要解开的视图控制器中。 - fullmoon
1
以下是有关 WWDC 视频的链接供参考,相关部分从大约37分钟开始:https://developer.apple.com/videos/play/wwdc2012-407/。 - Oz Solomon

11

从 unwind segue 返回数据的方法在这个 Apple Talk 中讲得非常好,在演示文稿的后半部分(编辑:从37:20开始)。

特别地,在 unwind segue 中,[segue sourceViewController] 是原始视图控制器,因此仍然处于活动状态并产生了 unwind 事件,所以可以像通常一样访问您的属性。


5
在关闭的控制器中添加prepareForSeque函数。
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 在取消操作之前调用此函数(例如,在您的示例中,您称其为quitQuiz)。 如您所见,它还有一个sender参数,以便您可以找出谁调用了取消操作并相应地收集相关数据。
例如,在WWDC 407视频中,如果您单击重置按钮,则不会设置accountInfo,而如果您单击完成按钮,则会设置。

1

设置代理并通知您的源视图控制器退出测验并发送数据。不要忘记将源视图控制器设置为目标视图控制器的代理。

// DestinationViewController.h
@protocol DestingationDelegate;
@interface 
...
@property (assign) id<DestinationDelegate> delegate;
...
@end

@protocol DestinationDelegate
-(void)didQuitQuiz:(NSDictionary*)infoDict;
@end

// DestinationViewController.m
-(IBAction)quitQuiz:(UIStoryboardSegue *)segue {
  NSLog(@"SEGUE unwind");
  if (self.delegate) [self.delegate didQuitQuiz:infoDict];
}


// SourceViewController.h
#import DestinationViewController.h
@interface SourceViewController : ViewController <DestinationDelegate>
....

// SourceViewController.m
-(void)didQuitQuiz:(NSDictionary *)infoDict {
    if (infoDict) {
       // do something with the data
    }
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
   ...
   destinationViewController.delegate = self;
}

1
协议很棒,但iOS6通过反向传递segue使生活变得更加轻松,这正是海报所询问的内容。 - Jeff

1

是的
为此,您需要创建属性来保存要从另一个视图控制器发送的数据:

    - (IBAction)unwindSelectFriendsVC:(UIStoryboardSegue *)segue
    {
        if ([segue.sourceViewController isKindOfClass:[ChildVC class]]) {

            ChildVC *child = (ChildVC *) segue.sourceViewController;

            //here we are passing array of selected friends by arrSelectedFriends property
            self.arrFriendList = child.arrSelectedFriends;
            [self.tableView reloadData];
        }
    }

0

在视图控制器之间传递数据通常使用协议来完成。以下是一个示例:

在您的测验视图控制器头文件中,声明一个类似的协议定义:

@protocol JBQuizViewControllerDelegate <NSObject>

@required
- (void)quizController:(id)controller didQuitWithState:(NSString *)state;

@end

在你的展示视图控制器的 prepareForSegue: 方法中,连接委托:
JBQuizViewController *destination = (JBQuizViewController *)segue.destinationViewController;
destination.delegate = self;

然后,在您的展示视图控制器中,处理委托协议的quizController:didQuitWithState:方法。

最后,一旦用户退出您的测验,您应该使用协议通知委托,传递状态或任何您想要公开的数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接