ViewController的自定义转场动画(UIViewControllerAnimatedTransitioning)

UIView的动画自由度一直很大,可以说想怎么动画怎么动画,但是UIViewController之间的动画一直都不好高度定制。

一般我会用的有:

  1. 系统提供的(UINavigationController,UITabbarController)
  2. ParentViewController上面加子ViewController,用transitionFromViewController来转场
  3. 再要不然就用2说的方法,然后控制Controller的View来动画了

然后我发现这样真的是太土了,iOS7以后UIViewControllerAnimatedTransitioning或者UIViewControllerContextTransitioning这些协议已经可以比较方便的自定义ViewController之间的动画了,比如修改UINavigationController的动画,下面举个例子来看一看如何做一个自定义的NavigationController的Push和Pop非交互动画

 自定义NavigationController动画

首先,实现一个非常简单的UINavigationController转场,一般会这么干

实现FirstViewController,加到Window上(没用storyboard和xib)

实现FirstViewController上面有个按钮,点击后push到SecondViewController

贴一下FirstViewController的关键代码,这很简单

那么就像下图这样,push进去动画有了,pop回来动画有了,手势pop回来也有

IMG_0001 IMG_0002

下面我们要自定义这个push动画

我们先实现一个push自定义动画类姑且叫做CustomPushAnimation,它实现UIViewControllerAnimatedTransitioning协议,用来定义一个非交互动画(就是动画过程中没交互)

里面也用到了UIViewControllerContextTransitioning这个协议,可以理解为转场动画的上下文,一个容器。下面是代码.h和.m,记住这是一个自定义的push的动画

 

 

下面在FirstViewController里面初始化CustomPush动画,并给FirstViewController添加UINavigationController代理

 

为什么要添加代理呢?怎么用这个CustomPush动画呢?

答案就是我们要用UINavigationControllerDelegate的

– (id<UIViewControllerAnimatedTransitioning>) navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC

这个方法来选中Push转场的时候用我们自己定义的CustomPush动画。

 

 

大功告成,现在就运行一下试试吧,可以发现动画像我想的一样,FirstViewController往左上角飘,SecondViewController紧随其后,这样完成了转场,这样我们就自定义了一个push的转场动画!

IMG_0003 IMG_0004

 

很有趣吧,下面照葫芦画瓢,做一个Pop动画吧!

考虑一下非对称的才是美,做一个从上往下的Pop转场,写一个CustomPopAnimation,代码如下:

 

聪明的你一定知道除了初始化这个pop外,只需要在自定义转场的代理里面加一个if语句判断pop就好

好了,运行!

IMG_0005 IMG_0006

自此,UINavigationController自定义转场就OK了

 

自定义PresentViewController动画

NavigationController搞定,Present也依葫芦画瓢

工程里添加第三个ViewController 叫做ThirdViewController,然后在FirstViewController里面添加下面代码

然后ThirdViewController添加一个按钮用来Dismiss自己,这个就不写了,然后运行起来实现的功能就很正常,点击Present按钮就会自下而上的一个动画推入新的ViewController,这很正常,然后现在来实现高级动画

首先,和Navigation类似,在FirstViewController我们要做一些准备工作

修改FirstViewController的协议

然后和NavigationController有区别的是给自己的“下家儿”,也就是要转去的ViewController设置代理

接下来就要在present时候和dismiss两个协议方法设置自定义动画,下面两个方法来于UIViewControllerTransitioningDelegate

那么,customPresent.animationType = AnimationTypePresent;这是什么东西呢?不要着急,这个就是自定义的Present动画效果,下面就讲他的实现,但是目前已经可以看到代码写起来和NavigationController的自定义动画非常像,对仗工整,都是协议,设置代理,调用代理时候使用自定义的动画。

下面定义真正的自定义动画CustomPresentAnimation.h

 

CustomPresentAnimation.m

调用的时候就和上面代码所说一样,在UIViewControllerTransitioningDelegate代理里完成,那么自定义的Present转场就是这样了。运行一下,会发现很调皮的ThirdView在Present转场的时候从左面弹性的进入屏幕。

交互式的动画

想想iOS7的UINavigationController自带的动画,可以用手指慢慢往左滑动来pop出一个页面,动画是随着手指的移动交互式呈现的,这个就很有趣了,那么除了系统帮我们实现的,我们自己也可以自定义交互式动画了。

下面就来给我们的App添加一个Pan手势,给之前实现的Present动画增加一个交互式功能。

FirstViewController的viewdidload添加pan手势

然后执行这个方法,在手势执行的时候刷新交互状态,核心方法是updateInteractiveTransition

这里需要提一下,初始化下面的代码,用于交互式转场,

//通过 UIViewControllerInteractiveTransitioning 协议进行交互转场。

    UIPercentDrivenInteractiveTransition* interactionController;

然后根据UIViewControllerTransitioningDelegate这个协议添加两个方法,来说明我们使用交互式转场

然后就可以交互式的观察present过程是随着我们手指移动动画的。

 

 

 

 

4个评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注