在该节主要介绍 UIKit 的一些动画API,动画作用于 UIView 或者 UIView 的子类。
Chapter 1: Getting Started
主要介绍 UIView.animate(...) 类方法通过改变视图的开始值与结束值动画改变:
位置
大小
透明度
背景色
或者通过 CGAffineTransform 对视图进行:
旋转
伸缩
更改位置
Chapter 2: Springs
为了使视图的动画效果更接近于现实世界,UIKit 还提供了一个如下方法
UIView.animate(withDuration: 1.0,
delay: 0.0,
usingSpringWithDamping: 0.4,
initialSpringVelocity: 10,
options: [],
animations: {
// change view properties
}) { finished in
// completion
}
使视图在动画的时候添加一定的弹性效果。其中
dampingRation的区间是 [0,1],
0 代表弹性最大;1 代表几乎没弹性
velocity代表的是初速度
Chapter 3: Transitions
Transitions主要对视图进行动画添加与移除
添加一个新视图
var animationContainerView: UIView!
override func viewDidLoad() {
//set up the animation container
animationContainerView = UIView(frame: view.bounds)
animationContainerView.frame = view.bounds
view.addSubview(animationContainerView!)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//create new view
let newView = UIImageView(image: UIImage(named: "banner")!)
newView.center = animationContainerView.center
//add the new view via transition
UIView.transition(with: animationContainerView,
duration: 0.33,
options: [.curveEaseOut, .transitionFlipFromBottom],
animations: {
self.animationContainerView.addSubview(newView)
},
completion: nil
)
}
移除一个视图
//remove the view via transition
UIView.transition(with: animationContainerView, duration: 0.33,
options: [.curveEaseOut, .transitionFlipFromBottom],
animations: {
self.newView.removeFromSuperview()
},
completion: nil
)
隐藏或者显示视图
//hide the view via transition
UIView.transition(with: self.newView, duration: 0.33,
options: [.curveEaseOut, .transitionFlipFromBottom],
animations: {
self.newView.isHidden = true
},
completion: nil
)
视图A替换视图B
//replace via transition
UIView.transition(from: oldView, to: newView, duration: 0.33,
options: .transitionFlipFromTop, completion: nil)
其实总结下来也就两个类方法:
UIView.transition from ViewA To ViewB
&
UIView.transition with ViewA
然后通过设置动画的options会有一些3D的效果
Chapter 4: View Animations in
主要是
UIView.transition(...)
UIView.animate(...)
someView.transform(...)
3个方法的混合练习
Chapter 5: Keyframe animations
想象一个场景,需要把一个视图做如下动画:
A移动到B;
B移动到C;
C移动到D
如果不怕麻烦可以如下不断地在 completion里面嵌套实现:
let sampleView = UIView()
UIView.animate(withDuration: 0.5, animations: {
sampleView.frame.origin = a
}) { _ in
UIView.animate(withDuration: 0.5, animations: {
sampleView.frame.origin = b
}) { _ in
UIView.animate(withDuration: 0.5, animations: {
sampleView.frame.origin = c
}) { _ in
UIView.animate(withDuration: 0.5, animations: {
sampleView.frame.origin = d
}) { _ in
}
}
}
}
}
但是这样实在不易于维护也不好看,如果是更复杂的动画效果就更加不好处理了。在这种情况就可以使用keyframe animation了,把上面的移动动画先单独分离出来,再用keyframes合并就好了。
实现如下:
let sampleView = UIView()
UIView.animateKeyframes(withDuration: 2.0, delay: 0.0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25, animations: {
sampleView.frame.origin = a
})
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: {
sampleView.frame.origin = b
})
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25, animations: {
sampleView.frame.origin = c
})
UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: {
sampleView.frame.origin = d
})
}) { _ in
// done
}
值得注意的是参数 withRelativeStartTime和 relativeDuration 都是相对值。比如整个运行时间是10秒的话,而相对开始时间 relativeStartTime = 0.5,那就是5秒开始了。
当然如果有一些其它的需求也可以在单独的 UIView.addKeyframe(...) 里面做一些背景色,透明度的动画;或者 伸缩,旋转等更复杂的transform动画