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
可以实现对象之间的交互,碰撞动画,重力动画等等
过程是这样的:
-
新建
UIDynamicAnimator
对象 -
新建
UIDynamicBehavior
对象,并将它添加到第一步的UIDynamicAnimator
对象中UIDynamicBehavior
是动画动作的父类,子类包括:UIAttachmentBehavior
,UICollisionBehavior
,UIGravityBehavior
,UIDynamicItemBehavior
,UIPushBehavior
,UISnapBehavior
-
给
Behavior
添加实现UIDynamicItem
protocol 的对象,UIView
已经实现了这个 protocol 所以可以直接使用
所有类的关系图
关于所有 UIDynamicAnimator
相关的类关系如图:
代码
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
就可以将其限制在屏幕中了