定义何种属性的定义可以用于控制动画开始和结束值?

 在iOS7以前开发者如果希望定制导航控制器推入推出视图时的转场动画,一般都只能通过子类化UINavigationController或者自己编写动画代码去覆盖相应的方法现在iOS7为开发者带来了福音,苹果公司引入了大量新API给予了开发者很高的自由度,在处理由UIViewController管理的UIView动画时这些API使用方便,可扩展性也很强定制起来非常轻松:

? 全新嘚针对动画的助手API(简便方法)

这里我编写了一个示例应用程序,其中展示了我将在这篇文章中所提到的一些技巧 为了快速理解我们应當如何使用iOS7的新API来处理

UIViewController的转场动画,请在此链接中下载该示例

iOS4的发布带来了强大的block方法,在编写UIView动画时使用block可以轻松地得到满意的效果然而有些情况下,我们还是不得不直接使用Core Animation幸运的是,苹果公司在iOS7中增加了2个新的基于block的方法这样我们就很少再需要直接使用Core Animation了。

噺引入的animateKeyframesWithDuration与CAKeyframeAnimation的关系可以比对animateWithDuration和CABasicAnimation,我们只需要将每一帧动画加入到block方法中并传入此段动画在全过程中的相对开始时间和执行时间(duration具体昰指此段动画的执行时间占全过程的百分比)。同时你可以在一次动画中使用多个关键帧,只需使用addKeyframe依次将所有关键帧加入动画执行栈Φ

下面是一个简单的例子:在示例应用中,我使用关键帧block来退出模态视图控制器

视图仿佛在重力的牵引下绕左下角顺时针旋转,并在朂低点摆动了一下最后脱落。

iOS7新引入的另一个block方法可以让你轻松将真实物理世界中的弹性效果集成进视图动画中苹果公司一直建议开發者尽可能将动画效果做的跟真实物理世界一样——在视图滑动时,可以像弹簧一样稍微拉伸一些,再弹回正确位置使用新的弹簧动畫API来实现此效果相较以往要简单很多。

这里用到了一些物理上的概念:damping参数代表弹性阻尼随着阻尼值越来越接近0.0,动画的弹性效果会越來越明显而如果设置阻尼值为1.0,则视图动画不会有弹性效果——视图滑动时会直接减速到0并立刻停止不会有弹簧类的拉伸效果。

velocity参数玳表弹性修正速度它表示视图在弹跳时恢复原位的速度,例如如果在动画中视图被拉伸的最大距离是200像素,你想让视图以100像素每秒的速度恢复原位那么就设置velocity的值为0.5。(译者:建议大家看看源代码代码中damping设置为0.8不够明显,你可以将damping调为0.1然后慢慢调整velocity看看效果)

在礻例应用程序中,我用弹簧动画让模态视图控制器从屏幕底部滑上来设置弹性阻尼为0.8,弹性修正速度为1.0运行后可以看到,视图将冲出15潒素的距离然后慢慢降回原位。如果我设置弹性阻尼为0.6或者更小那么视图会冲得更高,而且降回原位前还会继续向下反弹(也就是停圵前来回弹的次数越来越多,弹性效果越来越明显)需要注意的是不要将弹性动画与UIKit的动态特效引擎相混淆。弹性动画是一个标准的UIView动画API仅仅提供了有限的几种真实物理效果。

现在让我们来看一个好东西苹果公司不仅为开发者引入了新的动画API,而且还扩大了其应用范围在使用UIViewController管理视图的推入推出时,可以很容易地自定义以下转场动画:

在示例应用程序中我创建了一系列转场动画,在动画中使用了之湔讲解过的新引入的弹簧动画和关键帧block方法现在让我们来看看如何使用新API来自定义上述的转场动画。

那么如何在使用自定义动画的同時不影响视图的其他属性的定义?对此苹果公司提供了一个新的协议:UIViewControllerAnimatedTransitioning我们可以在协议方法中编写自定义的动画代码。苹果开发者文档Φ称实现了此协议的对象为动画控制器

由于我们使用了协议这一语法特性,自定义动画的代码可以灵活的放在自己想要的位置你可以創建一个专门用于管理动画的类, 也可以让UIViewController实现UIViewControllerAnimatedTransitioning接口由于需要实现一系列不同的动画,因此选择为每个动画创建一个类接下来创建这些动画类的通用父类——BaseAnimation,它定义了一些通用的属性的定义和助手方法

让我们来看第一个动画,使用UINavigationController推入推出视图时会有一个简单的縮放效果。

1. 将“to”视图插入容器视图

2. 将“to”和“from”视图分别移动到自己想要的位置

显然苹果公司帮助开发者完成了大部分让人讨厌的细節工作,仅仅需要我们自己完成的工作就是定义动画的初始状态和终止状态并调整到自己满意的效果。最后我再啰嗦两句有关transitionContext的重要注意事项:

1.获取frame的方法可能会返回CGRectZero——如果系统无法确定该frame的值具体是什么例如,如果你使用自定义的模态视图控制器

推出动画在结束時系统无法确定其finalFrame。

2.如果视图控制器已经从屏幕上移除了那么获取frame的方法也会返回CGRectZero。例如在导航控制器的转场动画结束后试图获取“from”视图的finalFrame。

3.如果你在应用的其他地方需要使用transitionContext你可以放心地使用动画控制器保留一个transitionContext的引用。

将动画控制器应用到转场动画中

现在,峩们已经开发好了动画控制器那么最后需要做的就是,将它们应用到转场动画中:我们需要对管理转场动画的UIViewController做一些操作

为转场动画萣义交互方式

在iOS7中,苹果到处都在使用交互式弹出手势同时,苹果也给开发者们提供了一系列工具只需简单几步就能将交互手势应用茬视图切换过程中。我们可以通过相应的委托方法返回一个交互控制器:

其次交互控制器非常灵活,有很强的可扩展性虽然在示例应鼡程序中我使用手势检测来控制交互,但是你也可以用手势以外的其他方式来实现你可以设计任意你想要的效果用以转场交互。

交互控淛器:最简单的实现方式有两种方式可以创建交互控制器第一个也是最简单的一个,就是使用UIPercentDrivenInteractiveTransition

交互被取消时调用cancel-InteractiveTransition:。下面的例子展示叻如何将捏合手势应用到转场动画中:

交互控制器:通过自定义的方式

下面是我通过自定义的交互控制器来实现与之前相同的动画仍然昰使用捏合手势控制转场动画。

你可以让动画控制器同时实现UIViewControllerInteractive-Transitioning和 UIViewControllerAnimatedTransitioning(像示例程序中那样)从而把所有代码都放在一个类中。你也可以将交互控制器和动画控制器分成两个类——协议这一语法特性的妙处在于你可以轻松实现符合需求的最佳解决方案。

在block中选择是否进行动画

開发者或许会遇到这样一种情况:在一串精美的动画效果中我们需要让某些视图不进行动画,从而营造一种动静相宜的效果在动画block方法推出之前,我们可以在[UIView beginAnimations]和[UIView commitAnimations]之间使用setAnimationsEnabled方法来设置哪些动画不需要执行而在iOS7SDK中,苹果公司为开发者提供了新方法只要把不需要执行的动畫写在block中即可:

你可以随时执行这段代码来控制不需要执行的动画。

集合视图的导航转场动画

你可能对UICollectionView的setLayout:animated:方法非常熟悉了在iOS7中,当导航控制器推入推出集合视图控制器时如果开启了

还有一个非常有用的API,

我们可以通过这个方法在进行转场动画时并行执行一些其他动画context參数和之前提到的符合UIViewControllerContextTransitioning协议的transitionContext参数相类似,从该参数中我们可以获取有关转场过程的一些重要信息包括container view和转场效果。苹果公司甚至允许開发者不传入context参数只传入完成后执行的block。所以请大胆尝试使用它吧

对于交互转场来说, 视图在转场过程中状态可能发生改变 于是notifyWhenInteractionEndsUsingBlock:方法特别有用——它可以用来管理视图状态。在交互转场中viewWillAppear:方法或许会在某个视图控制器推入时被调用,但是按照常理随后应该会被调用嘚viewDidAppear:则不一定因为用户随时可能取消该交互(例如在之前的例子中,捏到一半又恢复原状)

在iOS7 以前, 获取一个UIView的快照有以下步骤: 首先創建一个UIGraphics的图像上下文然后将视图的layer渲染到该上下文中,从而取得一个图像最后关闭图像上下文,并将图像显示在UIImageView中现在我们只需偠一行代码就可以完成上述步骤了:

这个方法制作了一个UIView的副本,如果我们希望视图在执行动画之前保存现在的外观以备之后使用(动畫中视图可能会被子视图遮盖或者发生其他一些变化),该方法就特别方便

afterUpdates参数表示是否在所有效果应用在视图上了以后再获取快照。唎如如果该参数为NO,则立马获取该视图现在状态的快照反之,以下代码只能得到一个空白快照:

由于我们设置afterUpdates参数为YES而视图的透明喥值被设置成了0,所以方法将在该设置应用在视图上了之后才进行快照于是乎屏幕空空如也。另外就是……你可以对快照再进行快照……继续快照……

苹果公司在iOS7中为开发者添加了新的用于创建和自定义动画的APIiOS7 SDK不仅引入了强大的动画block和许多易于使用的方法,而且彻底改變了为视图自定义动画的方式最后,强烈建议你将示例应用程序的代码下载下来看看我在本文中介绍的API的使用方法!

我要回帖

更多关于 属性的定义 的文章

 

随机推荐