Memo:
- The closure you passed to
UIViewPropertyAnimator
gets executed immediately.
if myView.alpha == 1.0 {
UIViewPropertyAnimator.runningPropertyAnimator(
withDuration: 3.0,
delay: 2.0,
options: [.allowUserInteraction],
animations: { view.alpha = 0.0 },
completion: { if $0 == .end { view.removeFromSuperview() } }
)
}
// let the views be three times bigger than the original size first
UIViewPropertyAnimator.runningPropertyAnimator(
withDuration: 0.6,
delay: 0,
options: [],
animations: {
self.myViews.forEach {
$0.transform = CGAffineTransform.identity.scaledBy(x: 3.0, y: 3.0)
}
},
completion: { position in
// do something you hope to achieve after animation is finished
}
)
- Dynamic animation: If animating views, all views must be in a view hierarchy with referenceView at the top. There are many dynamic animations, such as
collisionBehavior
,pushBehavior
and so on.
var animator = UIDynamicAnimator(referenceView: UIView)
let gravity = UIGravityBehavior()
animator.addBehavior(gravity)
let item1: UIDynamicItem = ... // usually a UIView
gravity.addItem(item1)
- we can create a subclass of
UIDynamicBehavior
and add as many behaviors as we want and overrideinit()
.
class CardBehavior: UIDynamicBehavior {
lazy var collisionBehavior: UICollisionBehavior = {
let behavior = UICollisionBehavior()
behavior.translatesReferenceBoundsIntoBoundary = true
return behavior
}()
lazy var itemBehavior: UIDynamicItemBehavior = {
let behavior = UIDynamicItemBehavior()
behavior.allowsRotation = false
behavior.elasticity = 1.0
behavior.resistance = 0
return behavior
}()
private func push(_ item: UIDynamicItem) {
let push = UIPushBehavior(items: [item], mode: .instantaneous)
push.angle = ...
push.magnitude = ...
push.action = { [unowned push, weak self] in
self?.removeChildBehavior(push)
}
addChildBehavior(push)
}
func addItem(_ item: UIDynamicItem) {
collisionBehavior.addItem(item)
itemBehavior.addItem(item)
}
func removeItem(_ item: UIDynamicItem) {
collisionBehavior.removeItem(item)
itemBehavior.removeItem(item)
}
override init() {
super.init()
addChildBehavior(collisionBehavior)
addChildBehavior(itemBehavior)
}
convenience init(in animator: UIDynamicAnimator) {
self.init()
animator.addBehavior(self)
}
}
- Add animation using UIView transition
UIView.transition(with: myView,
duration: 0.6,
options: [.transitionFlipFromLeft],
animations: {
// put the thing you want to animate
})
- It's perfectly fine to add animation in the completion handler of another animation.