使用內置的curves動畫
前面我們一直使用的系統內置的一些curves效果,比如:linear, ease in, ease out, ease in out。
打開LockScreenViewController.swift添加如下代碼
func blurAnimation(_ blurred: Bool) -> () -> Void {
return {
self.blurView.effect = blurred ? UIBlurEffect(style: .dark) : nil
self.tableView.transform = blurred ? CGAffineTransform(scaleX: 0.75, y: 0.75) : .identity
self.tableView.alpha = blurred ? 0.33 : 1.0
}
}
移除viewDidLoad中的兩行代碼:
blurView.effect = UIBlurEffect(style: .dark)
blurView.alpha = 0
修改toggleBlur(_:)爲:
func toggleBlur(_ blurred: Bool) {
UIViewPropertyAnimator(duration: 0.55, curve: .easeOut, animations: blurAnimation(blurred)).startAnimation()
}
這樣我們就爲UISearchBar添加了一個淡入淡出的動畫,運行效果:
自定義貝塞爾曲線動畫
具體的貝塞爾曲線概念可以參考這篇文章,通俗易懂,繪製曲線效果可以到這裏。
通過設置貝塞爾曲線的兩個控制點(二階貝塞爾曲線),自定義動畫曲線:
func toggleBlur(_ blurred: Bool) {
UIViewPropertyAnimator(duration: 0.55,
controlPoint1: CGPoint(x: 0.57, y: -0.4),
controlPoint2: CGPoint(x: 0.96, y: 0.87),
animations: blurAnimations(blurred))
.startAnimation()
}
通過設置不同的控制點,可以得到不同的動畫曲線效果。controlPoint座標的取值範圍爲-1.0~1.0。
彈簧動畫
UIViewPropertyAnimator的第三個實例方法UIViewPropertyAnimator(duration:dampingRatio:animations:) ,類似我們前面學習到的UIView.animate的彈簧動畫。
自定義Timing對象構造動畫
UIViewPropertyAnimator的第四個實例方法UIViewPropertyAnimator(duration:timingParameters:)。
第二個參數timingParameters的類型UITimingCurveProvider,它是一個協議對象,UIKit中有兩個類遵守了該協議:UICubicTimingParameters和UISpringTimingParameters。UICubicTimingParameters很好理解,通過內置的curves效果或者通過貝塞爾曲線控制點來初始化。
我們來看一下UISpringTimingParameters。
通過阻尼係數和初速度初始化,代碼如下
let spring = UISpringTimingParameters(dampingRatio: 0.5, initialVelocity: CGVector(dx: 1.0, dy: 0.2))
let animator = UIViewPropertyAnimator(duration: 1.0, timingParameters: spring)
spring對象相當於在配置你的彈簧,然後將它運用到animator動畫中去。初速度是一個可選類型的二維矢量類型,你可以運用於position和size等二維變量添加動畫,如果你爲alpha或者一維變量添加動畫,那麼UIKit將僅僅使用二維矢量中的dx值。
通過質量、彈性係數、阻尼係數、初速度構造彈簧,代碼如下
let spring = UISpringTimingParameters(mass: 10.0, stiffness: 5.0, damping: 30, initialVelocity: CGVector(dx: 1.0, dy: 0.2))
let animator = UIViewPropertyAnimator(duration: 1.0, timingParameters: spring)
自動佈局動畫
爲自動佈局添加UIViewPropertyAnimator動畫,在AnimatorFactory.swift添加方法:
@discardableResult
static func animateConstraint(view: UIView, constraint: NSLayoutConstraint, by: CGFloat) -> UIViewPropertyAnimator {
let spring = UISpringTimingParameters(dampingRatio: 0.2)
let animator = UIViewPropertyAnimator(duration: 2.0, timingParameters: spring)
animator.addAnimations {
constraint.constant += by
view.layoutIfNeeded()
}
return animator
}
在LockScreenViewController.swift中添加動畫:
AnimatorFactory.animateConstraint(view: view, constraint: dateTopConstraint, by: 100).startAnimation()
運行效果
下面爲"Show More"添加動畫
@IBAction func toggleShowMore(_ sender: UIButton) {
self.showsMore = !self.showsMore
let animation = {
self.widgetHeight.constant = self.showsMore ? 230 : 130
if let tableView = self.tableView {
tableView.beginUpdates()
tableView.endUpdates()
tableView.layoutIfNeeded()
}
}
}
調用beginUpdates和endUpdates將告訴所有的cell調整它們的佈局。
編寫動畫代碼
let spring = UISpringTimingParameters(mass: 30, stiffness: 1000, damping: 300, initialVelocity: CGVector(dx: 5, dy: 0))
toggleHeightAnimator = UIViewPropertyAnimator(duration: 0.0, timingParameters: spring)
toggleHeightAnimator?.addAnimations(animation)
toggleHeightAnimator?.startAnimation()
widgetView.expanded = showsMore
widgetView.reload()
運行效果
更改標題"Show More",使用UIView.transition動畫
let textTransition = {
UIView.transition(with: sender, duration: 0.25, options: .transitionCrossDissolve, animations: {
sender.setTitle(
self.showsMore ? "Show Less" : "Show More",
for: .normal)
}, completion: nil)
}
toggleHeightAnimator?.addAnimations(textTransition, delayFactor: 0.5)
運行效果