前言:

iOS里使用闭包对UIView对象可进行简洁而又强大的动画效果设置。与Android不同的是,后者需要设置xml及动画类才能完成复杂的动画效果,而iOS仅使用animatetransition属性闭包便可完成。

在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属性。

下面为单层闭包常见的动画效果设置属性:

  • frame:位置和尺寸的动画设置
  • bounds:尺寸设置
  • center:中心位置修改
  • transform:形态变化
  • alpha:透明度
  • backgroundColor:背景颜色
  • contentStretch:视图内的内容拉伸模式

当然,常见的动画效果还有“弹性阻尼”这样的内容,如下:

@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,其余均一致。