iOS動畫:UIViewPropertyAnimator動畫之貝塞爾曲線(15)

使用內置的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添加了一個淡入淡出的動畫,運行效果:
image_1

自定義貝塞爾曲線動畫

具體的貝塞爾曲線概念可以參考這篇文章,通俗易懂,繪製曲線效果可以到這裏
通過設置貝塞爾曲線的兩個控制點(二階貝塞爾曲線),自定義動畫曲線:

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()

運行效果
image_2
下面爲"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()

運行效果
image_4
更改標題"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)

運行效果
image_4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章