一、简介
unwind segue通过允许你定义一个控制器和其他控制器的关系来扩展segue的概念,这个“关系”先于顺传(流式控制)的方式。基于unwind segue可以实现导航相反的效果,即将界面返回到一个已经存在的控制器实例。在大多数情况下,unwind segue可以代替“代理”(delegate)来将数据回传到之前的某个控制器。
一个unwind segue相当于一个触发的transition,这一点和segue类似;不同的是,unwind segue 是返回到一个在众多的用户界面中已经存在的某个控制器。一个unwind segue包含以下信息:
1. 事件源。即触发segue的对象。
2. 来源控制器。注意和顺传时的来源控制器区分开来。
3. 一个用来选择目标控制器的unwind 方法。
4. 一个用来标识segue的可选的字符串。
提示:unwind segue不包含目标控制器,这样设计是为了实现跳转的任意性(即可以跳转到任何一个你想跳转的控制器),其中目标控制器是在运行时确定的。
二、如何使用unwind segue
(1)在给app添加unwind segue之前,需要定义至少一个unwind 方法。定义unwind方法的要求是:
1.是objective-C方法;
2. 拥有一个唯一的参数,参数类型是UIStoryboardSegue;
3. 返回值类型是IBAction;
4. 对方法名称没有特殊要求,但建议起名具有唯一性和可读性。如下所示:
-(IBAction)unwindToLoginVc:(UIStoryboardSegue *)sender{
}
unwind 方法是为unwind segue而准备,在unwind segue触发时用来选择目标控制器的。因此,必须在每一个想要跳回的控制器中定义unwind方法。例如:控制器A将控制器B呈现到屏幕,那么控制器A内部应该定义一个unwind方法。同时,在控制器B中通过storyboard上的按钮连线unwind 方法。
(2)在storyboard中添加unwind segue
1.自动unwind Segue
按住 control建,将场景(scene)中的对象和其他控制器的exit图标 进行连线,连线时选择弹出的方法即可。在xcode6中,先右键点击exit图标,选择要连线的方法,然后和要连线的对象进行连线。
2. 手动unwind Segue
按住control键,点击控制器的viewController图标,拖线到该控制器的exit图标。
成功添加unwind Segue后,就能在场景面板中看到它了。与Segue一样,手动型unwind Segue需要提供一个标识字符串。通过调用
performSegueWithIdentifier:sender:
方法执行unwind Segue。
三、unwind 处理过程
1. 一个控制器被选作unwind segue的目标控制器
2. 来源控制器发送一条 prepareForSegue: sender: 消息,默认不做任何事。可以重写这个方法来传递数据给目标控制器。
3. 目标控制器发送一条消息,回应unwind segue的unwind 方法。
4. unwind segue 开始在来源控制器和目标控制器之前传递数据。
注意:控制器容器还有一些需要处理的东西。如果自定义了控制器容器,如自定义导航控制器,也需要参与到unwind 处理过程中来。(后面会说到)
四、unwind segue如何选择目标控制器
当unwind segue触发时,unwind segue必须找到符合要求的控制器作为目标控制器。如果没有找到,unwind segue执行会被取消。搜索顺序如下:
1.一条
viewControllerForUnwindSegueAction:fromViewController:withSender:
消息发送给来源控制器的父控制器。默认的实现是:检查消息接收者是否想处理unwind方法,如果是,返回消息接收者;否则,会搜索消息接收者的子控制器。canPerformUnwindSegueAction:fromViewController:withSender: 方法会被用来决定给定控制器是否能执行unwind action。
2.一条
viewControllerForUnwindSegueAction:fromViewController:withSender:消息发送给下一个父控制器......
提示:如果有特殊的业务需求,可以重写
canPerformUnwindSegueAction:fromViewController:withSender:方法。需要注意的是,如果消息接收者想处理unwind action,必须返回YES。
五、控制器容器
控制器容器在unwind segue 处理过程中有2件事要处理,如果你使用的控制器容器是SDK提供的,例如UINavigationController,这2件事是自动处理的。
(1)选择一个子控制器来处理unwind action
重写
- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender方法。如果没有子控制器想处理unwind action,在方法内部应该调用父类的方法 并返回结果。
(2)在2个子控制器之间传递数据
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
谭家泉
2015-01-02 15:56:25