资讯专栏INFORMATION COLUMN

iOS中的转场研究(2)

wenzi / 1558人阅读

摘要:而中的则是对转场流程的进一步封装。这个概念在中至关重要,也是实现自定义转场的关键角色。在的框架中,和都是常用的。之所以引入,是为了应付任意跳转的情况,即从任意一个转场到特定的。在上面的原理说明中,这个父是。

自iOS5引入Storyboard之后,iOS开发者在除了原有的Nib开发的基础上又有了新的方式来组织自己的UI和流程。Storyboard相对于传统的Nib,能够更加清晰的体现业务的流程,因此很受开发者欢迎。如今,很多教程都以Storyboard开发方式来讲解。而Storyboard中的Segue则是对转场流程的进一步封装。这个概念在Storyboard中至关重要,也是实现自定义转场的关键角色。

自定义Segue

自定义Segue的方式很简单,只要创建一个UIStoryboardSegue子类,并实现其perform方法即可。一个简单的实现如下:

- (void)perform 
{
    // Modal presentation segue
    UIViewController *fromController = self.sourceViewController;
    UIViewController *toController = self.destinationViewController;

    [fromController presentViewController:toController animated:YES completion:^{
        // Completion code here
    }];
}

或者

- (void)perform 
{
    // Navigation ViewController segue(Push segue, Show segue in iOS8).
    UIViewController *fromController = self.sourceViewController;
    UIViewController *toController = self.destinationViewController;

    [fromController.navigationController pushViewController:toController animated:YES];
}
自定义Unwind Segue

自定义Unwind Segue的方式与上面几乎完全一样,只不过调用的接口由presentViewController:animated:completion:pushViewController:animated:换成dismissViewControllerAnimated:completion:popToViewController:animated:
但是Unwind Segue与普通的Segue有一个很大的不同,就是Unwind Segue的调用通常是由一个Container View Controller完成的。在iOS SDK的UIKit框架中,Navigation View Controller和TabBar View Controller都是常用的Container View Controller。

那么为什么Unwind Segue需要一个Container View Controllerl的支持?

这里就需要提一下Unwind Segue的设计初衷及其工作方式。之所以引入Unwind Segue,是为了应付任意跳转的情况,即从任意一个View Controller转场到特定的View Controller。在Nib的时代,这种工作往往通过delegate来完成。但是有了Unwind Segue以后,我们只要在需要跳转到的这个特定的View Controller类中实现一个签名为- (IBAction)unwindMethod:(UIStoryboardSegue *)segue这样的方法即可(其中unwindMethod可以替换为任何你喜欢的名称,但注意,当存在多个这样的方法时,名称不要相同,以免发生冲突,造成不可预料的后果)。这样,我们就可以在任意的View Controller(除了含有这个方法本身的View Controller)通过连接Segue来实现任意View Controller跳转到当前View Controller。不用再多写一行代码,这些都可以通过Interface Builder搞定,非常方便。

Unwind Segue的工作原理大致如下1:

当我们通过UI事件或手动调用performSegueWithIdentifier:sender:方法触发一个Unwind Segue以后,首先UIKit会发送canPerformUnwindSegueAction:fromViewController:withSender:消息到sourceViewController询问是否处理UnwindSegue的action,由于sourceViewController不能处理(Unwind到自身没有意义),会返回NO

UIKit然后会寻找sourceViewController的父Controller。如果sourceController是嵌入Navigation View Controller的子Controller,那么父Controller就是其navigationController

之后UIKit会发送viewControllerForUnwindSegueAction:fromViewController:withSender:消息给navigationController,询问能否找到一个负责处理此action的子Controller

在navigationController的默认viewControllerForUnwindSegueAction:fromViewController:withSender:实现中,navigationController会向自己的navigation栈上的所有子Controller发送canPerformUnwindSegueAction:fromViewController:withSender:消息。UIViewController类中,该方法的默认实现会查看unwinde segue action定义是否存在(即上面提到的特定签名的方法是否存在,这个方法的内部实现可以留空),若存在就返回YES。

如果navigationController的viewControllerForUnwindSegueAction:fromViewController:withSender:方法返回nil,则不会触发任何Unwind Segue

如果navgationController找到一个子类可以处理Unwind Segue的action,那么UIKit会发送segueForUnwindingToViewController:fromViewController:identifier:消息给navigationController,此方法将返回一个实际执行定制转场的segue实例

调用sourceViewController上的prepareForSegue:sender:方法

调用由viewControllerForUnwindSegueAction:fromViewController:withSender:方法返回的destinationViewController中的Segue action方法

调用Unwind Segue实例中的perform方法

从上面的我们可以知道,Unwind Segue的正常工作必须要有一个Container View Controller作为所有流程View Controller的父Controller来管理整个流程。在上面的原理说明中,这个父Controller是Navigation View Controller。如果我们要实现一个自己的定义的Container,就必须给自定义的View Controller类实现一些上面提到过的方法:

canPerformUnwindSegueAction:fromViewController:withSender:

viewControllerForUnwindSegueAction:fromViewController:withSender:

segueForUnwindingToViewController:fromViewController:identifier:

关于这些方法的说明和实现方式,我将在下一篇文章中详细讨论。


参考iOS6 by Tutorial ↩

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15502.html

相关文章

  • iOS中的转场研究(1)

    摘要:在中,可以通过多种方式设定转场效果。若想详细了解的用法,可以读一读苹果的文档。以后,苹果引进了新的。这些的使用方式,苹果没有给出一个官方的,但是在网上,已经有很多和教程讲解如何使用这些,比如这篇文章。 场景转换是iOS开发中最基本的需求。为了让自己的App更加的酷炫,我们往往需要定制一些转场效果。在iOS中,可以通过多种方式设定转场效果。这里简单列表如下: Modal prese...

    qc1iu 评论0 收藏0
  • iOS中的转场研究(3)

    摘要:使用时需要注意的情况当我们使用的方法以的方式来跳转场景的时候,情况与在有很大不同。因此实现风格的的时候,动画的不能搞错,必须对中的顶层操作。而以正确的方式重写这些方法并不容易。下面的代码修改自中的示例代码。 实现自定义的Container View Controller 上一篇文章中提到了如何定制Segue。我们知道Unwind Segue的正常工作需要Container View ...

    RyanHoo 评论0 收藏0
  • iOS系统中导航栏的转场解决方案与最佳实践

    摘要:背景目前,开源社区和业界内已经存在一些导航栏转场的解决方案,但对于历史包袱沉重的美团而言,这些解决方案并不完美。中的导航栏属于各个业务方的公用资源,由于缺乏相应的约束机制和最佳实践,导致业务方之间的代码耦合程度不断增加。 背景 目前,开源社区和业界内已经存在一些 iOS 导航栏转场的解决方案,但对于历史包袱沉重的美团 App 而言,这些解决方案并不完美。有的方案不能满足复杂的页面跳转场...

    wangbjun 评论0 收藏0
  • iOS相关

    摘要:多线程是通过提高资源网络请求之与的二次封装及意义之后,被苹果抛弃,该来的即便是迟些,但最终肯定会来。注意,不是线程安全的,但是线程安全的。也就是说,因为忙导致的触发时刻超出了的情况下,并不会取消,而不执行回调。 超简单!!! iOS 设置状态栏、导航栏按钮、标题、颜色、透明度,偏移等 // 一行代码搞定导航栏颜色navBarBarTintColor = .white// 一行代码搞定导...

    renweihub 评论0 收藏0
  • 一行代码调用支持手势返回的iOS自定义转场动画

    摘要:原文来自我的简书前言在平时的开发中,我们进行界面跳转时一般都是采用系统默认的转场动画和,之后,苹果开放了相关让我们可以自定义转场动画,让更有活力。效果图如下现在支持左滑上滑下滑右滑四种手势进行返回,可以通过属性修改。 原文来自:我的简书 前言 在平时的开发中,我们进行界面跳转时一般都是采用系统默认的转场动画(Push 和 Present),iOS7之后,苹果开放了相关API,让我们可以...

    learn_shifeng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<