VC容器的主要目的是解决将不同VC添加到同一个屏幕上的需求,以及可以提供一些简单的自定义切换效果。使用VC容器可以使view的关系正确,使添加的VC能够正确接收到例如屏幕旋转,viewDidLoad:等VC事件,进而进行正确相应。VC容器确实可以解决一部分问题,但是也应该看到,对于自定义切换效果来说,这样的解决还有很多不足。首先是代码高度耦合,VC切换部分的代码直接写在container中,难以分离重用;其次能够提供的切换效果比较有限,只能使用UIView动画来切换,管理起来也略显麻烦。iOS 7提供了一套新的自定义VC切换,就是针对这两个问题的。
iOS 7 自定义ViewController动画切换
自定义动画切换的相关的主要API
在深入之前,我们先来看看新SDK中有关这部分内容的相关接口以及它们的关系和典型用法。这几个接口和类的名字都比较相似,但是还是能比较好的描述出各自的职能的,一开始的话可能比较迷惑,但是当自己动手实现一两个例子之后,它们之间的关系就会逐渐明晰起来。(相关的内容都定义在UIKit的UIViewControllerTransitioning.h中了)
@protocol UIViewControllerContextTransitioning
这个接口用来提供切换上下文给开发者使用,包含了从哪个VC到哪个VC等各类信息,一般不需要开发者自己实现。具体来说,iOS7的自定义切换目的之一就是切换相关代码解耦,在进行VC切换时,做切换效果实现的时候必须要需要切换前后VC的一些信息,系统在新加入的API的比较的地方都会提供一个实现了该接口的对象,以供我们使用。
对于切换的动画实现来说(这里先介绍简单的动画,在后面我会再引入手势驱动的动画),这个接口中最重要的方法有:
-(UIView *)containerView;// VC切换所发生的view容器,开发者应该将切出的view移除,将切入的view加入到该view容器中。 -(UIViewController )viewControllerForKey:(NSString )key; //提供一个key,返回对应的VC。现在的SDK中key的选择只有UITransitionContextFromViewControllerKey和UITransitionContextToViewControllerKey两种,分别表示将要切出和切入的VC。 -(CGRect)initialFrameForViewController:(UIViewController *)vc; //某个VC的初始位置,可以用来做动画的计算。 -(CGRect)finalFrameForViewController:(UIViewController *)vc; //与上面的方法对应,得到切换结束时某个VC应在的frame。 -(void)completeTransition:(BOOL)didComplete; //向这个context报告切换已经完成。
@protocol UIViewControllerAnimatedTransitioning
这个接口负责切换的具体内容,也即“切换中应该发生什么”。开发者在做自定义切换效果时大部分代码会是用来实现这个接口。它只有两个方法需要我们实现:
-(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext;
系统给出一个切换上下文,我们根据上下文环境返回这个切换所需要的花费时间(一般就返回动画的时间就好了,SDK会用这个时间来在百分比驱动的切换中进行帧的计算,后面再详细展开)。
-(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext;
在进行切换的时候将调用该方法,我们对于切换时的UIView的设置和动画都在这个方法中完成。
@protocol UIViewControllerTransitioningDelegate
这个接口的作用比较简单单一,在需要VC切换的时候系统会像实现了这个接口的对象询问是否需要使用自定义的切换效果。这个接口共有四个类似的方法:
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForPresentedController:(UIViewController )presented presentingController:(UIViewController )presenting sourceController:(UIViewController *)source; -(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed; -(id< UIViewControllerInteractiveTransitioning >)interactionControllerForPresentation:(id < UIViewControllerAnimatedTransitioning >)animator; -(id< UIViewControllerInteractiveTransitioning >)interactionControllerForDismissal:(id < UIViewControllerAnimatedTransitioning >)animator;
前两个方法是针对动画切换的,我们需要分别在呈现VC和解散VC时,给出一个实现了UIViewControllerAnimatedTransitioning接口的对象(其中包含切换时长和如何切换)。后两个方法涉及交互式切换,之后再说。
原文:
https://onevcat.com/2013/10/vc-transition-in-ios7/