Swift 动画相关 Animcation: UIDynamicAnimator

对 ​​UIView​​ 属性的动画

​UIViewPropertyAnimator​​​ 可以实现对于 UIView 元素的 ​​frame​​​, ​​center​​​, ​​alpha​​​, ​​transform​​ 这些属性的变换

使用的时候,直接调用 ​​UIViewPropertyAnimator​​​ 中的 ​​runningPropertyAnimator​​ 方法

UIViewPropertyAnimator.runningPropertyAnimator(
withDuration: 2,
delay: 0,
options: [.curveEaseInOut, .allowUserInteraction],
animations: {
let animatingView = self.view.viewWithTag(100)!
animatingView.center = CGPoint.zero
}) { (animationPosition) in

}

注意:
​​​animation​​ 中的代码是立即执行的, 只是动画后来才展示给用户,但结果已经执行完了

options

  • ​repeat​​ 不断重复
  • ​autoreverse​​ 执行完动画又逆向再执行一遍

对整个 UIView 的动画

这个方法是 ​​UIView​​ 的方法

func transition(with view: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
UIView.transition(with: animatingView,
duration: 1,
options: .transitionFlipFromLeft,
animations: {
animatingView.backgroundColor = UIColor.magenta
animatingView.center = CGPoint(x: animatingView.frame.midX - 20, y: animatingView.frame.midY - 50)
},
completion: nil)

UIDynamicAnimator

​UIDynamicAnimator​​ 可以实现对象之间的交互,碰撞动画,重力动画等等

过程是这样的:

  1. 新建​​UIDynamicAnimator​​ 对象
  2. 新建​​UIDynamicBehavior​​ 对象,并将它添加到第一步的 ​​UIDynamicAnimator​​ 对象中

​UIDynamicBehavior​​​ 是动画动作的父类,子类包括:​​UIAttachmentBehavior​​​, ​​UICollisionBehavior​​​, ​​UIGravityBehavior​​​, ​​UIDynamicItemBehavior​​​, ​​UIPushBehavior​​​, ​​UISnapBehavior​


  1. 给​​Behavior​​ 添加实现 ​​UIDynamicItem​​ protocol 的对象, ​​UIView​​ 已经实现了这个 protocol 所以可以直接使用

所有类的关系图

关于所有 ​​UIDynamicAnimator​​ 相关的类关系如图:

Swift 动画相关  Animcation: UIDynamicAnimator_UIDynamic

代码

import UIKit

class AnimationDymanicVC: UIViewController {

// 1. create Animator
lazy var animator = UIDynamicAnimator(referenceView: view)

override func viewDidLoad() {
super.viewDidLoad()
let ballView = BallView(frame: CGRect(origin: view.center, size: CGSize(width: 60, height: 60)))
ballView.isOpaque = false
view.addSubview(ballView)

// 2. create behavior
let gravityBehavior = UIGravityBehavior()

// 3. add behavior to animator
animator.addBehavior(gravityBehavior)

// 4.add item to behavior
// UIDynamicItem 是个 protocol, UIView 已经实现了这个 protocol
gravityBehavior.addItem(ballView)
// 当 item 添加到 Animator的时候,这个元素属于 Animator,如何你想更新这个元素,需要调用这个方法
// animator.updateItem(usingCurrentState: UIDynamicItem)

let collisinoBehavior = UICollisionBehavior()
collisinoBehavior.translatesReferenceBoundsIntoBoundary = true
collisinoBehavior.addItem(ballView)
animator.addBehavior(collisinoBehavior)
}
}


class BallView: UIView {
override func draw(_ rect: CGRect) {
let path = UIBezierPath(ovalIn: rect)
path.lineWidth = 1
UIColor.orange.setFill()
UIColor.yellow.setStroke()
path.stroke()
path.fill()
}

override func layoutSubviews() {
super.layoutSubviews()
}
}

只有重力作用的时候是这样的,元素会直接飞出屏幕。添加 ​​CollisionBehavior​​ 就可以将其限制在屏幕中了

Swift 动画相关  Animcation: UIDynamicAnimator_UIview_02
Swift 动画相关  Animcation: UIDynamicAnimator_xcode_03