iOS里使用闭包对UIView对象可进行简洁而又强大的动画效果设置。与Android不同的是,后者需要设置xml及动画类才能完成复杂的动画效果,而iOS仅使用animate与transition属性闭包便可完成。
在iOS里动画可简单分为属性过渡动画与转场动画,而属性过渡动画可分为单层闭包动画、双层闭包动画与多参数闭包动画,下面是其具体介绍。
属性过渡是指某UIView (注意所有控件为其派生类)某些属性改变时,将改变过程以渐变效果进行动画展示。
所谓单层闭包动画即为使用了一层闭包的动画。下面以单击一个Button后界面上的UIView颜色改变为例。
import UIKit
import SnapKit
class AnimationViewController: BaseViewController {
private var animationView: UIView!
private var buttonChange: UIButton!
private func initView(){
animationView = UIView()
animationView.backgroundColor = UIColor.gray
self.view.addSubview(animationView)
buttonChange = UIButton(type: UIButton.ButtonType.system)
buttonChange.setTitle("Change", for: UIControl.State.normal)
buttonChange.addTarget(self, action: #selector(animatingViewListener), for: UIControl.Event.touchDown)
self.view.addSubview(buttonChange)
animationView.snp.makeConstraints{ make in
make.size.equalTo(230)
make.center.equalToSuperview()
}
buttonChange.snp.makeConstraints{ make in
make.width.equalTo(60)
make.height.equalTo(30)
make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-80)
make.centerX.equalToSuperview()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
initView()
}
@objc func animatingViewListener(){
UIView.animate(withDuration: 1){
self.animationView.backgroundColor = UIColor.red
}
}
}
当然,我们不仅仅可以设置单机后颜色改变,还可以设置位置、大小等属性。该效果的实现方法解释如下:
UIView.animate(withDuration: TimeInterval) {
// Code here.
}
withDuration参数为Int类型,意为动画持续时间,单位s;其后接一闭包,里面便为要改变的UIView属性。
下面为单层闭包常见的动画效果设置属性:
当然,常见的动画效果还有“弹性阻尼”这样的内容,如下:
@objc func animatingViewListener(){
UIView.animate(withDuration: 2, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: [], animations: {
self.animationView.center = CGPoint(x: 200, y: 200)
}, completion: nil)
}
弹性阻尼的实现方法解释如下:
第一个参数为动画持续时长;第二个为延迟时长。第三个为阻尼系数,范围0到1,0表示剧烈回弹,1表示无回弹;第四个为回弹初速度,范围0到1。
双层闭包即为使用了两个闭包,常用于上一个闭包执行完后需要执行下一个闭包。
@objc func animatingViewListener(){
UIView.animate(withDuration: 1, animations: {
self.animationView.backgroundColor = UIColor.red
}) {(finish) in
UIView.animate(withDuration: 1, animations: {
self.animationView.center = CGPoint(x: 200, y: 200)
})
}
}
多参数闭包即为多个参数的闭包,options数组选项提供了多种效果。
@objc func animatingViewListener(){
UIView.animate(withDuration: 2, delay: 0, options: UIView.AnimationOptions.curveEaseInOut, animations: {
self.animationView.backgroundColor = .red
}, completion: nil)
}
下面是opntions数组的解释说明。
属性 | 说明 |
---|---|
layoutSubviews | 子视图随父视图展示动画 |
allowUserInterraction | 允许事件交互 |
beginFromCurrentState | 允许动画执行时再执行新的动画 |
repeat | 重复 |
autoreverse | 逆向执行 |
overrideInheritedDuration | 使用内层动画执行时间 |
overrideInheritedContent | 使用内层动画的变速效果 |
allowAnimatedContent | 允许实时刷新 |
showHideTransitionViews | 视图展示时是切换而飞隐藏 |
overrideInheritedOptios | 不实用任何动画参数 |
curveEaseInout | 淡入淡出 |
curveEaseIn | 淡入 |
curveEaseOut | 淡出 |
curveEaseLinear | 线性匀速 |
transitionFlipFromLeft | 从左侧切入 |
transitionFromRight | 从右侧切入 |
transitionCurlUp | 从上到下立体翻入 |
transitionCurlDown | 从下到上立体翻入 |
transitionCrossDissolve | 溶解效果 |
transitionFlipFromTop | 从顶部切入 |
transitionFlipFromBottom | 从底部切入 |
所谓转场是指由一个界面转变为另一个界面。当然,有些情况下是并非转变了ViewControleller,而是转变了内容,如一般的图书阅读器,转换的仅为里面的内容。那么这种情况下使用的动画就为转场动画。
转场动画分为真转场(切换了View)与伪转场(没切换)。下面以伪转场为了说明:
@objc func animatingViewListener(){
UIView.transition(with: self.animationView, duration: 2, options: UIView.AnimationOptions.transitionCurlUp, animations: {
self.animationView.backgroundColor = UIColor.red
}, completion: nil)
}
transition() 方法与 animate() 方法参数类似,不再赘述。真转场使用的方法如下:
UIView.transition(with: UIView, duration: 0, options: UIView.AnimationOptions.transitionCurlUp, animations: {
// Code here.
}, completion: nil)
可以看到真转场使用的方法第一个参数为待转场的UIView,其余均一致。