自定义过渡动画

本文由我们团队的王瑞华童鞋撰写。


在iOS 7 发布之后,UI上的两个重要的变化是丰富的动画使用和界面上各个方面对真实物理世界的模拟。然而交互式自定义过渡不是一个新特性,至少在iOS 3.2 中就已经存在了。例如,翻页动画就不仅是从一个页面到另一个的过渡。它是一个交互式过渡——随着手指移动的过渡。交互式自定义过渡是提升应用品质,使其在 App Store 大放异彩的重要工具。iOS 7 之后 SDK 允许自定义大部分过渡,包括视图控制器的出现和消失、UINavigationController 的推入和淡出过渡、UITabBarController 的过渡,甚至是集合视图的布局变化过渡。

UICollectionView 的过渡动画

在iOS 7 之后的日历和照片应用当中,就运用集合视图的过渡方式实现了一个viewController 向另一个 viewControler 的过渡。在 UICollectionViewController 中引入了 useLayoutToLayoutNavigationTransitions 这一属性。当此属性设置为 YES 时,在将 collecionViewController 推入导航控制器之前,推入过渡会使用 -setColletionViewLayout:animated:来完成集合视图布局的变化。开发者要做的只是设置 useLayoutToLayoutNavigationTransitions = YES,剩下的交给系统处理便可以。注意,该方法要求两个 collectionView 拥有相同的数据。

自定义 viewController 过渡

实现 transition delegate 是 transition 动画和自定义 presentation 的起点。该 transition delegate 就是开发者定义一个对象并遵循 UIViewControllerTransitioningDelegate 协议。下面看看该协议中包含什么。

示意图如下:

112376458-9e03ed2b9441b316

解释了这么多,对过渡动画需要遵循的 delegate 已经有了初步的了解,下面通过present 的方式实现一个 push 动画。

  1. 我们首先创建两个 viewController VC1 和 VC2,我们要实现 VC1 present 出 VC2,同时模拟 push 和 pop 动画的效果。
  2. 然后我们需要创建出两个管理过渡动画的类,用于管理 present 动画和 dismiss 动画,两个管理类大体实现相似。在 viewController类中遵从 UIViewControllerTransitioningDelegate 协议,实现协议方法。

以下是 present 动画的实例,dismiss 动画与之相似,不再赘述。

CustomPushAnimation.h

使用交互式自定义过渡

交互式过渡是由事件驱动的。可以是动作事件或者手势,通常为手势。要实现一个交互式过渡,除了需要跟之前相同的动画,还需要告诉交互控制器动画完成了多少。开发者只需要确定已经完成的百分比,其他交给系统去做就可以了。例如,(平移和缩放的距离 / 速度的量可以作为计算完成的百分比的参数)。

交互式控制器实现了 UIViewControllerInteractiveTransitioning 协议,该协议中包含如下方法:

这个方法里只能有一个动画块,动画应该基于 UIView 而不是图层,交互式过渡不支持 CATransitionCALayer 动画。

交互式过渡的交互控制器应当是 UIPercentDrivenInteractiveTransition 子类。动画类负责计算完成百分比,系统会自动更新动画的中间状态。

根据手势移动或者缩放的距离,计算出百分比并调用相应方法。

下面是简单的交互式过渡的代码片段,该事例只做了交互式 dismiss 的部分,也只罗列了比较关键的部分。

SecondViewController.m

CustomInteractiveTransition.m

UIViewControllerTransitionCoordinator 过渡协调器

所有的过渡都会创建一个过渡协调器,无论是否自定义。也就是说,当执行默认的模态过渡或push过渡时,也可以对视图中的其他部分做动画。

在 iOS中,可以取消一个过渡。这意味着,第二个视图的 -viewWillApear 被调用,但 -viewDidApear不一定被调用。如果代码写的假定 -viewDidAppear 总是在 -viewWillAppear 之后执行则需要重新考虑逻辑实现。这种情况下UIViewControllerTransitionCoordinator 就有用了。在交互式过渡结束的时候,会在 block 中收到通知。

Demo在这

1 2 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部