上一篇文章中介绍了 UIKit 中一些基础动画,这些动画足够应付普通的动画交互。但是作为开发者仅仅掌握基础用法显然是不够的,我们需要更强大的武器来应对将来可能的复杂场景。接下来我们来看看 UIView 的进阶动画:Transitions、Keyframe Animations。
Transitions
在上一篇文章中介绍了基于属性修改实现的动画,但是如果需要你实现视图的添加和移除的交互动画呢?当然你可以使用基础动画实现,但是这里将介绍新的动画类型 - Transitions。不同于基础动画通过在起始和结束状态之间的时间线上插值的实现过程,Transitions 会采用一种更为自然的方式来展现动画过程。
上面的效果图中:我们翻转了头像视图,添加了红色视图然后又将其替换为蓝色视图。主要的代码实现如下:
// 头像翻转 UIView.transition(from: backView!,to: avatorView,duration: 1,options: [.transitionCrossDissolve],completion: nil) // 添加红色视图 UIView.transition(with: animationContainserView!,animations: { self.animationContainserView!.addSubview(redView) },completion: { finished in let blueView = UIView.init(frame: CGRect.init(x: 0,y: 0,width: 60,height: 60)) blueView.backgroundColor = UIColor.blue // 替换红色视图 UIView.transition(from: redView,to: blueView,completion: nil) })
其中第一个函数中,我们将 backView 从其父视图中移除,并将 avatorview 添加进去。而第二个函数中我们将红色视图 newView 添加到参数 animationContainserView 代表的视图中。其中控制动画过渡效果的是
options 中的参数,其可与之前基本动画中的选项进行组合,具体参数意思:
transitionFlipFromLeft 以垂直方向为轴从左到右翻转
transitionFlipFromRight 以垂直方向为轴从右到左翻转
transitionFlipFromTop 以水平方向为轴从上往下翻转
transitionFlipFromBottom 以水平方向为轴从下往上翻转
transitionCurlUp 右下角往后翻书效果
transitionCurlDown 右下角往前翻书效果
transitionCrossDissolve 交叉消失
Keyframe
前面那么介绍的那么多动画大多都可以看作是单一的线形动画,但是对于类型飞机起降这样的复杂动画来说则远远不够。其实动画就是很多图片在时间线上组成的关键帧组合,如果能对其中某些关键帧进行提取并组合那么灵活性将大大提高。万幸的是 Apple 早就为我们做好了一切,先看效果图:
这里我们主要关注的是飞机起降过程的动画实现,其他动画后面又机会再讲。真实的起降过程远比效果图复杂,但是这里我们进行了简化。起飞过程大致如下图所示:先平飞、然后调整角度、然后快速拉升。
知道了整个动画的几个关键帧我们就可以进行如下代码实现了:
UIView.animateKeyframes(withDuration: 1.5,delay: 0.0,options: [],animations: { //add keyframes UIView.addKeyframe(withRelativeStartTime: 0.0,relativeDuration: 0.25,animations: { self.planeImage.center.x += 80.0 self.planeImage.center.y -= 10.0 }) UIView.addKeyframe(withRelativeStartTime: 0.1,relativeDuration: 0.4) { self.planeImage.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_4/2)) } UIView.addKeyframe(withRelativeStartTime: 0.25,relativeDuration: 0.25) { self.planeImage.center.x += 100.0 self.planeImage.center.y -= 50.0 self.planeImage.alpha = 0.0 } UIView.addKeyframe(withRelativeStartTime: 0.51,relativeDuration: 0.3) { self.planeImage.center = CGPoint(x: 0.0,y: originalCenter.y - 40) self.planeImage.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_4/2)) } UIView.addKeyframe(withRelativeStartTime: 0.75,relativeDuration: 0.45) { self.planeImage.transform = CGAffineTransform.identity self.planeImage.alpha = 1.0 self.planeImage.center = originalCenter } },completion: nil)
在函数 animateKeyframes 中我们依次添加了滑跑、调整角度、快速拉升、调整降落位置和角度、降落这五个关键帧,而每一个关键帧中的动画设计几乎与基础动画一样简单。所以只要我们能够对类似起降这样复杂动画的关键帧进行很好的提取和组合,那么一切都不在话下了。
总结
UIKit 框架中的动画大部分都在这篇文章中介绍,还有一些新的动画特性后面再将。接下来文章中将会把目光投入到 Core Animations 中,内容将会在之前的基础上探索更多动画相关的特性。Let's Go!