当弹出一个view controller时,UIKit提供了一些标准转换动画,而且也支持用户自定义的动画效果。 app
1 UIView动画 ide
UIView是自带动画实现功能,其中有两种方式实现: 函数
1) animateWithDuration系列方法 测试
2) transitionFromViewController方法 动画
1.1 animateWithDuration ui
只要在该方法的animations block中修改UIView的动画属性,那么便可实现动画变换,因此为container viewController中实现不一样view controller之间的动画切换,只要改变了UIView的动画属性便可以实现变换。 spa
如在调用viewMove方法以前,fromVC为显示状态,而toVC为未显示状态。因此调用时便可实现动画切换: code
1.2 transitionFromViewController 对象
UIView同时提供了视图切换方法,同时可支持动画变换,即transitionFromViewController方法。从而能够在container viewController中调用该方法来实现视图的变换。 blog
如在当前viewController有两个子视图控制器:fromVC和toVC,而且fromVC为显示状态。因此能够调用transitionFromViewController方法来实现动画切换。
2 转换动画次序
转换动画是交互两个view controller的内容,其中存在两种转换类型:弹出(presentation)和撤回(dismissal)。
1) presentation:这种动画是指在app的view controller层次结构中添加新的view controller;
2) dismissal:这种动画是指从app的view controller层次结构中移除view controller。
2.1 转换delegate
转换delegate是一个实现了UIViewControllerTransitioningDelegate协议的对象,其工做是提供以下之一的对象:
1) Animator对象:
该对象是实现了UIViewControllerAnimatedTransitioning协议的实体。其功能是负责以动画的形式显示或隐藏view controller的视图。转换delegate向那些进行presenting 和dismissing操做的实体提供Animator对象。
2) Interactive animator对象:
该对象是实现了UIViewControllerInteractiveTransitioning协议的实体。其也是实现动画操做,但可在动画过程当中与用户进行事件交互。
3) Presentation controller:
当view controller在屏幕时,presentation controller负责管理弹出(presentation)的样式。系统已提供了一些内置样式,同时也支持用户自定义更多的presentation样式。
若要实现自定义动画,须要设置新弹出view controller的transitioningDelegate属性为遵照UIViewControllerTransitioningDelegate协议的对象,同时要修改新弹出view controller的modalPresentationStyle属性为常量UIModalPresentationCustom。
图 312 The custom presentation and animator objects
如图 312所示,绿色表示 Presenting view controller(主动弹出),蓝色为Presented view controller(被动弹出),被弹出的VC有个Transitioning Delegate属性,经过这个属性可得到Animator、Interactive Animator和Presentation Controller对象。
2.2 执行时序
1) Present view controller
当被弹出view controller的transitioningDelegate属性是一个有效对象时,UIKit将按指定的动画弹出这个view controller。在准备阶段UIKit会从UIViewControllerTransitioningDelegate协议(称为转换delegate)调用错误! 超连接引用无效。:方法,从而来查询指定的动画对象,若该对象有效,则UIKit会按以下步骤执行:
a) UIKit会调用转换delegate的interactionControllerForPresentation:方法,若该方法返回nil,那么UIKit将不与用户进行交互的执行动画。
b) UIKit调用animator对象的transitionDuration:方法来查询动画的执行时间。
c) UIKit调用相应方法开始执行动画:
*若为非交互动画,则调用animator对象的animateTransition:方法;
*若为交互动画,则调用interactive animator的startInteractiveTransition:方法。
d) UIKit等待动画对象调用context transitioning的completeTransition:方法来等完成动画。
在自定义的动画中,须要手动调用transitionContext对象的completeTransition方法来完成动画操做。
2) Dismiss view controller
当消除一个view controller时,UIKit会调用UIViewControllerTransitioningDelegate协议(称为转换delegate)中的animationControllerForDismissedController:方法,并按以下步骤执行程序:
a) UIKit会调用转换delegate的interactionControllerForDismissal:方法,若该方法返回nil,那么UIKit将不与用户进行交互的执行动画。
b) UIKit调用animator对象的transitionDuration:方法来查询动画的执行时间。
c) UIKit调用相应方法开始执行动画:
*若为非交互动画,则调用animator对象的animateTransition:方法;
*若为交互动画,则调用interactive animator的startInteractiveTransition:方法。
d) UIKit等待动画对象调用context transitioning的completeTransition:方法来等完成动画。
在自定义的动画中,须要手动调用transitionContext对象的completeTransition方法来完成动画操做。
注意:
当在实现动画体结束时必须手动调用completeTransition:方法来结束操做。
2.3 转换Context对象
在转换动画开始以前,UIKit会建立一个transitioning context对象,并将一些如何执行动画的信息填充到该对象中,这些信息包括Presenting view controller、Presented view controller、container view controller,以及是否与用户进行交互的信息。其中context对象是实现了UIViewControllerContextTransitioning协议。
如图 313所示,白色方块表示container view(不是controller)、绿色表示Presenting view controller、蓝色表示Presented view controller,虚线表示引用,实线表示方法。Animator对象经过animateTransition:方法得到context对象,而context经过自身的containerView:方法得到container VC。
图 313 The transitioning context object
2.4 转换Coordinator对象
无论是内置的转换仍是自定义的转换,UIKit都会建立一个Coordinator对象帮助动画的执行。除了Present和dismissal view controller外,转换还可能发生在view cotroller的frame发生变化时。在动画过程当中,能够经过Coordinator对象得到一些信息。如图 314所示,图形语义与图 313同样。
图 314 The transition coordinator objects
3 使用自定义动画
使用自定义的动画实现Present(弹出)view controller,须要进行以下操做:
1)建立一个Presented view controller;
2)建立一个已经实现了UIViewControllerTransitioningDelegate协议的对象,并将其赋值给Presented view controller对象的transitioningDelegate属性。
3)调用presentViewController:animated:completion:方法弹出新的view controller,而且须要将YES传递给该方法的animated参数。
4 实现转换delegate
如图 312所示,转换delegate的功能是为Present和dismissal操做,提供Animator、Interactive animator
和Presentation controller三种对象。因此实现UIViewControllerTransitioningDelegate协议也就是实现那些可以获取这三个对象的方法。
以下是实现一个能获取Animator对象的方法:
5 实现动画delegate
为了实现UIViewControllerAnimatedTransitioning协议须要实现两个方法:
1) transitionDuration: transitionContext:返回动画持续的时间;
2) animateTransition: transitionContext:执行具体动画的方法;
其中animateTransition方法是重点,主要工做都是在实现该方法中,其中能够将实现该方法分为以下三个步骤:
a) 获取与动画有关的参数;
b) 经过core Animation或UIView animation实现动画;
c) 完成动画操做。
5.1 获取参数
当实现animateTransition方法时,其会传递一个transitionContext参数,能够经过这个参数可以得到与动画相关的信息:
1) 经过viewControllerForKey:方法得到在转换时的"from"和"to" view controller;
2) 经过containerView方法得到动画的超类,从而将全部的子view添加到这个container view中;
3) 经过viewForKey:方法得到被添加或被删除的view,其中在转换过程当中要么是被添加,要么是被删除的view。
4) 经过finalFrameForViewController:方法得到最后被添加或删除后view 的frame矩形。
因为动画对象能够向Present和dismissal操做提供动画,因此经过transitionContext获取的"from"和"to" view controller语义有些差别。如图 315所示,当执行Present操做时,是将"to" view controller添加到container层次结构中;而当执行dismissal操做时,是将"from" view controller从container层次结构中移除。
图 315 The from and to objects
5.2 实现动画
为了实现动画效果,在animateTransition:方法中必须完成两部分的内容:
a) 以动画的形式修改presented view controller中的view位置;
b) 将presented view controller中的view添加到container view的层次结构中。
1) Presentation 动画
对于执行弹出动画,能够按以下步骤完成配置:
a) 经过transitionContext对象的viewControllerForKey: 和viewForKey:方法得到view controllers 和views对象。
b) 设置"to" view的起始位置,同时也可修改其它属性值。
c) 经过transitionContext对象的finalFrameForViewController:方法获取"to" view的最终位置。
d) 将 "to" view添加到container view的层次结构中。
e) 建立动画
2) Dismissal动画
消除view controller的动画与弹出的操做类似,一样也可按以下步骤完成配置:
a)经过transitionContext对象的viewControllerForKey: 和viewForKey:方法得到view controllers 和views对象。
b) 计算presented view controller的view(便是"from" view)最终位置,该view为被清除的view。
c) 仍是将 "to" view添加为container view的子view。
d) 建立动画
5.3 测试实例
1) 场景
如要实现图 316所示的两种动画操做,在A视图中弹出B视图,而且能够在B视图将其自身推出返回到A视图。
图 316 A custom presentation and dismissal
2) 实现动画Delegate
用户须要建立已经实现了UIViewControllerAnimatedTransitioning协议的对象,以下是MyAnimator类的具体实现,在该类的animateTransition:方法中实现了两种动画效果(Presentation和Dismissal),其中Presenting为YES时,表示实现Presentation操做;当Presenting为NO时,表示实现Dismissal操做,这个Presenting在构造函数中进行初始化。固然也能够将两种操做分别实如今不一样的对象中。
3) 实现转换Delegate
在弹出动画前,须要先给Presented view controller对象设置transitioningDelegate属性,而设置的对象为UIViewControllerTransitioningDelegate协议的实现类。以下是一种实现方式,因为被弹出的view controller有两种动画效果(Presentation和Dismissal),因此须要实现animationControllerForPresentedController和animationControllerForDismissedController方法分别弹出两种不一样的动画对象。
4) 实现弹出操做
上述的转换delegate和动画delegate都已经实现完成,接下来就是要实现转换视图的响应方法。即firstViewController为图 316的A视图控制器,而thirdViewController为图 316的B视图控制器。而customAnimation:方法为按钮的响应方法,在该方法中调用presentViewController方法来弹出thirdViewController视图(即B视图)。
其中须要注意的是mtd属性,不能将其声明为customAnimation方法内的局部变量,不然将致使Dismissal操做不能实现动画,由于在该方法推出后,mtd变量的生命周期将结束,从而在Dismissal操做时其已经无效,因此这里将mtd声明为成员属性,固然若firstViewController类自身实现了UIViewControllerAnimatedTransitioning协议,那么能够将transitioningDelegate设置为self。
5) 实现退出操做
在被弹出视图(B视图)中,只需实现退出按钮的响应方法(dismissal),从而在该方法中调用dismissViewControllerAnimated方法推出操做。
6 添加交互对象
UIKit支持添加一个交互对象,经过这个对象用户能在进行弹出等操做时,控制动画的动做。为转换delegate添加一个交互对象也很是简单,只需在其interactionControllerForPresentation方法中返回一个遵照UIViewControllerInteractiveTransitioning协议的对象便可。能够直接实现该协议,也能够继承UIPercentDrivenInteractiveTransition类,但都需重载startInteractiveTransition方法。
最后须要注意的是,因为转换动画仍是执行UIViewControllerTransitioningDelegate协议中animationControllerForPresentedController方法返回的对象,但动画开始执行的时间还是在调用finishInteractiveTransition方法后。
以下所示的实例:
1) 实例场景
用户在点击视图的按钮后,须要再点击视图中的空白区域,才能实现转换及动画。从而本例只是在3.3.5.3小节所示的基础上添加一个交互对象,因此对其它内容都无需修改,只是添加的交互类myInteractiveAnimator,及在myTransitioningDelegate类中添加了一个interactionControllerForPresentation方法,在该方法中返回一个交互对象。
2) 实现交互类
本例采用继承UIPercentDrivenInteractiveTransition类的方式实现交互,从而实现了startInteractiveTransition方法。在该方法中添加了一个点击手势识别器,并在响应方法中启动动画转换。
3) 返回交互对象
以下是在3.3.5.3小节所示的myTransitioningDelegate类基础上添加了interactionControllerForPresentation方法,其它方法都是原来的内容。
iOS UIKit:viewController文章参考文献
[1] View Controller Programming Guide for IOS
[3] 建立Unwind Segue
[4] UIViewControllerTransitioningDelegate Protocol Reference.
[5] UIViewControllerContextTransitioning Protocol Reference.
[6] UIViewControllerInteractiveTransitioning Protocol Referrence