iOS自定义转场动画
关于iOS的转场动画的实现:
转场动画实际上就是对View添加的转场效果,在CATransiton就已经给我们提供了丰富的事例
所以ViewController控制器之间的转场,其实还是对VC.view的操作,不过因为ViewController的层级更复杂一些,所以需要先进行一些其他的操作。
在实现自定义转场动画之前,我们需要先了解实现ViewController转场动画执行的流程。
整体流程大致可以分为三步:
第一步:调用系统push/pop或者present/dismiss方法,获取到VC跳转的代理方法
第二步:在系统跳转代理方法中,提供一个控制两个View的实例对象,作为View转场动画的载体
第三部:实现自定义动画(UIViewAnimation或者CAAnimation),并添加到这个实例中
接下来对这三步进行详细说明:
1.首先实现第一步,在push/pop时获取的到系统执行转场的代理方法:
这里先给ViewController添加了一个分类Transition,用来统一调用push/present方法。transitionManager是从外部传进来的实例对象,后面会讲到。
在分类实现自定义的跳转方法
从上图可以看到,在两个跳转方法中都设置了delegate代理对象为transitionManager。点进去查看源码后,发现系统给ViewController提供了一个分类:UIViewControllerTransitioning
在上图中可以看到,分类中包含了一个UIViewControllerTransitioningDelegate协议,这个协议就是我们获取系统push/present代理方法的关键,只要我们给transitioningDelegate属性设置代理对象,就能获取到系统跳转的代理方法。上图中只给出了ViewController的情况,如果是NavigationController类,协议就是UINavigationControllerDelegate,需要给UINavigationControllerDelegate设置代理对象。
下面我们新建一个继承自NSObject的类:TransitionManager类,上面transitionManager就是这个类的实例对象。并且遵守UINavigationControllerDelegate和UIViewControllerTransitioningDelegate这两个协议。
在TransitionManager中,分别实现协议中的中转场代理方法
1.model模态视图present/dismiss方法
2.push/pop视图方法
这样第一步我们就获取到了VC跳转的代理方法。
2.接着是第二步:获取载体实例
在上面截取的部分代码中不难发现,在获取到系统跳转方法以后,我们都返回了一个transitionContext实例对象,这里使用transitionContext对象来作为实现转场动画载体实例对象。
跟第一步一样,我们还是要先创建一个继承自NSObject的类:TransitionContext类,并且遵守了UIViewControllerContextTransitioning这个协议,这个协议就是我们获取载体实例的关键。
遵守了这个协议以后,在.m文件中实现下面的系统方法,就能获取到transitionContext对象作为执行view转场动画的载体,我们还给这个类添加了一个block属性,用于回调获取到的这个载体实例。
接下来就是最后一步了。
3.第三步:实现转场动画
在第一步的跳转代理方法中,我们返回了一个transitionContext对象,其实这个对象就是由第二步的block回调得到。现在将使用这个对象来实现我们的转场动画。使用懒加载初始化TransitionManager的中定义的TransitionContext实例对象
在TransitionManager的.h文件中,还定义了setToAnimation:和setBackAnimation:两个方法。在这两个方法中来实现转场动画的具体动画代码。
但是直接在TransitionManager中编写,会让TransitionManager变得十分臃肿,所以对于每一个具体转场动画的实现,这里都会新建一个继承自TransitionManager的子类,来专门实现setBackAnimation和setBackAnimation转场动画的具体代码。
项目中创建一个继承自TransitionManager的类:CircleSpreadAnimation类,自定义一个实例化方法。
实现setToAnimation和setBackAnimation。
这里代码较多,只贴出了一少部分。接下来就是如何调用
这里定义了两个控制器CircleSpreadFromViewController、CircleSpreadToViewController,在CircleSpreadFromViewController传入了点击位置、动画初始半径和动画持续时间,一个完整的转场动画就完成了。
使用上面的系统协议,基本上就能实现自定义转场动画,这里是代码部分。
除此之外,在第一步获取系统跳转时,也可以使用runtime的Method_ExchangeImplementations,替换系统push/present方法。后面的第二、三步思路不变。