• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • [Animations] 快速上手 iOS10 屬性動畫

    標簽: iOS10 屬性動畫

    概述

    今天要說的UIViewPropertyAnimator, 是iOS10新的API

    詳細

    基礎動畫, 核心動畫到自定義轉場動畫其實都不是什么新東西了, 所以我也是草草看一遍就能夠讀個大概, 但今天要說的UIViewPropertyAnimator, 是iOS10新的API, 其他的好處我還不太清楚, 但抽象動畫邏輯和監控動畫的進程上真的是方便很多。

    一、準備工作

    對于屬性動畫來說, 真的是個新知識, 想必會用的還不多, 我也是近期才有涉及, 理解不周還望大伙指點一二, 之前我們要做一些稍微高級的動畫都會使用核心動畫的方法, 但是核心動畫有一個致命的弱點, 就是假象和被打斷, 所以iOS10出了新的API真的是造福我們這些開發者. 不多說, 先了解新的API:

    @available(iOS 10.0, *)
    open class UIViewPropertyAnimator : NSObject, UIViewImplicitlyAnimating, NSCopying
      @NSCopying open var timingParameters: UITimingCurveProvider? { get }
      open var duration: TimeInterval { get }
      open var delay: TimeInterval { get }
      open var isUserInteractionEnabled: Bool
      open var isManualHitTestingEnabled: Bool
      open var isInterruptible: Bool
    • timingParameters: 時間參數

    • duration: 持續時間

    • delay: 延遲時間

    • isUserInteractionEnabled: 是否可交互

    • isManualHitTestingEnabled: 是否啟動手動測試

    • isInterruptible: 是否可被打斷

    構造方法:

    public init(duration: TimeInterval, timingParameters parameters: UITimingCurveProvider)
    • duration: 持續時間

    • timingParameters: 時間參數

    public convenience init(duration: TimeInterval, curve: UIViewAnimationCurve, animations: (@escaping () -> Swift.Void)? = nil)
    • duration: 持續時間

    • curve: 動畫曲線

    • animations: 動畫執行閉包

    public convenience init(duration: TimeInterval, controlPoint1 point1: CGPoint, controlPoint2 point2: CGPoint, animations: (@escaping () -> Swift.Void)? = nil)
    • duration: 持續時間

    • controlPoint1: 控制點1

    • controlPoint2: 控制點2

    • animations: 動畫執行閉包

    public convenience init(duration: TimeInterval, dampingRatio ratio: CGFloat, animations: (@escaping () -> Swift.Void)? = nil)
    • duration: 持續時間

    • dampingRatio: 減震比率

    • animations: 動畫執行閉包

    運行屬性動畫方法:

    open class func runningPropertyAnimator(withDuration duration: TimeInterval, delay: TimeInterval, options: UIViewAnimationOptions = [], animations: @escaping () -> Swift.Void, completion: (@escaping (UIViewAnimatingPosition) -> Swift.Void)? = nil) -> Self
    • duration: 持續時間

    • options: 動畫選項

    • animations: 動畫執行閉包

    • completion: 動畫完成閉包

    添加動畫組方法:

    open func addAnimations(_ animation: @escaping () -> Swift.Void, delayFactor: CGFloat)
    • animation: 動畫執行閉包

    • delayFactor: 延遲比率, 按照百分比計算 范圍0~1

    動畫組完成方法:

    open func addCompletion(_ completion: @escaping (UIViewAnimatingPosition) -> Swift.Void)
    • completion: 完成執行閉包

    繼續動畫方法:

    open func continueAnimation(withTimingParameters parameters: UITimingCurveProvider?, durationFactor: CGFloat)
    • withTimingParameters: 時間參數

    • durationFactor: 持續比率, 按照百分比計算 范圍0~1

    動畫狀態:

    @available(iOS 10.0, *)
    public enum UIViewAnimatingState : Int {
        case inactive // The animation is not executing.
        case active // The animation is executing.
        case stopped // The animation has been stopped and has not transitioned to inactive.
    }

    動畫位置:

    @available(iOS 10.0, *)
    public enum UIViewAnimatingPosition : Int {
        case end
        case start
        case current
    }

    動畫協議:

    public protocol UIViewAnimating : NSObjectProtocol
    @available(iOS 10.0, *)
        public var state: UIViewAnimatingState { get }
        public var isRunning: Bool { get }
        public var isReversed: Bool { get set }
        public var fractionComplete: CGFloat { get set }
        public func startAnimation()
        public func startAnimation(afterDelay delay: TimeInterval)
        public func pauseAnimation()
        public func stopAnimation(_ withoutFinishing: Bool)
    @available(iOS 10.0, *)
        public func finishAnimation(at finalPosition: UIViewAnimatingPosition)
    • state: 動畫狀態

    • isRunning: 動畫是否在執行

    • isReversed: 動畫是否反向執行

    • fractionComplete: 分段完成 范圍0~1

    • startAnimation: 開始執行動畫

    • startAnimation(afterDelay:): 延遲執行動畫

    • pauseAnimation: 暫停動畫執行

    • finishAnimation: 完成動畫知悉在某個動畫位置

    二、實戰實例

    這次的API有點多, 因為本人也是第一次接觸所以把每個都嘗試了一遍, 我們就來使用這些API進行實戰, 和之前一樣, 我們就通過Stroyboard搭建界面 (由于Demo代碼較多, 只列舉具體的動畫部分)

    我們首先先將動畫抽象到一個類中:

    class AnimatorFactory {
        ...
    }

    添加縮放動畫:

    static func scaleUp(view: UIView) -> UIViewPropertyAnimator {
        let scale = UIViewPropertyAnimator(duration: 0.33, curve: .easeIn) //屬性動畫初始化
        scale.addAnimations { //添加動畫組
          view.alpha = 1.0
        }
        scale.addAnimations({ //添加動畫組
          view.transform = .identity
        }, delayFactor: 0.33) //延遲33%執行
        scale.addCompletion {_ in //完成后打印
          print("ready")
        }
        return scale
      }

    添加搖晃動畫:

    @discardableResult //去除黃色警告
      static func jiggle(view: UIView) -> UIViewPropertyAnimator {
        return UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.33, delay: 0, //直接執行屬性動畫
          animations: {
    
            UIView.animateKeyframes(withDuration: 1, delay: 0, //關鍵幀動畫
              animations: {
    
                UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25) {
                  view.transform = CGAffineTransform(rotationAngle: -.pi/8)
                }
                UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.75) {
                  view.transform = CGAffineTransform(rotationAngle: +.pi/8)
                }
                UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 1.0) {
                  view.transform = .identity
                }
              },
              completion: nil
            )
          },
          completion: {_ in
            view.transform = .identity //完成后置空
          }
        )
      }

    添加淡入淡出動畫:

    @discardableResult
      static func fade(view: UIView, visible: Bool) -> UIViewPropertyAnimator {
        return UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.5, delay: 0.1,
          options: [.curveEaseOut], 
          animations: {
            view.alpha = visible ? 1 : 0
          }
        )
      }

    添加約束動畫:

    @discardableResult
      static func animateConstraint(view: UIView, constraint: NSLayoutConstraint, by: CGFloat) -> UIViewPropertyAnimator {
        let spring = UISpringTimingParameters(dampingRatio: 0.55) //這個和之前的彈簧動畫類似
        let animator = UIViewPropertyAnimator(duration: 1.0, timingParameters: spring)
        animator.addAnimations {
          constraint.constant += by //約束操作
          view.layoutIfNeeded() //刷幀
        }
        return animator
      }

    添加閃爍動畫:

    static func grow(view: UIVisualEffectView, blurView: UIVisualEffectView) -> UIViewPropertyAnimator {
        // 1
        view.contentView.alpha = 0
        view.transform = .identity
    
        // 2
        let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeIn)
    
        // 3
        animator.addAnimations {
          UIView.animateKeyframes(withDuration: 0.5, delay: 0.0, animations: {
    
            UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1.0) {
              blurView.effect = UIBlurEffect(style: .dark)
              view.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
            }
    
            UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
              view.transform = view.transform.rotated(by: -.pi/8)
            }
          })
        }
    
        // 4
        animator.addCompletion {position in
          switch position {
            case .start:
              blurView.effect = nil
            case .end:
              blurView.effect = UIBlurEffect(style: .dark)
            default: break
          }
        }
        return animator
      }

    進行屬性動畫的調用:

    @IBAction func toggleShowMore(_ sender: UIButton) {
    
        self.showsMore = !self.showsMore
    
        let animations = { //創建動畫組閉包
          self.widgetHeight.constant = self.showsMore ? 230 : 130
          if let tableView = self.tableView {
            tableView.beginUpdates() //進行tableView刷新動畫
            tableView.endUpdates()
            tableView.layoutIfNeeded() //刷布局
          }
        }
    
        let textTransition = { //View轉場
          UIView.transition(with: sender, duration: 0.25, options: .transitionCrossDissolve,
            animations: {
              sender.setTitle(self.showsMore ? "Show Less" : "Show More", for: .normal)
            },
            completion: nil
          )
        }
    
        if let toggleHeightAnimator = toggleHeightAnimator, toggleHeightAnimator.isRunning { 
          toggleHeightAnimator.addAnimations(animations)
          toggleHeightAnimator.addAnimations(textTransition, delayFactor: 0.5)
        } else {
          let spring = UISpringTimingParameters(mass: 30, stiffness: 1000, damping: 300, initialVelocity: CGVector.zero)
          toggleHeightAnimator = UIViewPropertyAnimator(duration: 0.0, timingParameters: spring) //初始化動畫
          toggleHeightAnimator?.addAnimations(animations) //添加動畫組
          toggleHeightAnimator?.addAnimations(textTransition, delayFactor: 0.5)
          toggleHeightAnimator?.startAnimation() //開始動畫
        }
    
        widgetView.expanded = showsMore
        widgetView.reload()
      }


    三、運行效果

    1、運行效果

    2、文件截圖

    blob.png

    注:本文著作權歸作者,由demo大師(http://www.demodashi.com)宣傳,拒絕轉載,轉載需要作者授權


    版權聲明:本文為findhappy117原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/findhappy117/article/details/79329690

    智能推薦

    material—animations簡單操作activity過渡動畫

    Material-Animations gihub下載地址:https://github.com/lgvalle/Material-Animations 總體分四部分,簡單的過渡動畫,分享元素的過渡動畫,通過Transition實現的view動畫,ReveaAimation四種,接下來都以此介紹一下。 簡單過渡動畫 簡單的過渡動畫分三種吧,Slide,Fade,Explode,滑動,漸變,爆炸三種...

    翻譯:iOS視圖控制器編程指南(十)——自定義過渡動畫(Customizing the Transition Animations)

    過渡動畫提供應用界面改變的視覺反饋。UIKit提供一組標準過渡樣式,用于present視圖控制器時使用,你可以自定義過渡補充標準過渡。 過渡動畫序列 過渡動畫互換視圖控制器的內容。有兩種類型的過渡:present和dismiss。present過渡會在應用視圖層級結構中添加一個新的視圖控制器,而dismiss過渡會從層級結構中刪除一個或多個視圖控制器。 過渡動畫的實現需要很多對象。UIKit提供所...

    iOS10本地通知UserNotifications快速入門

    https://www.jianshu.com/p/5713fa2bfece notification.png iOS10更新變動最大的就是通知這部分了,新版通知變得更加統一,使用更加方便,設計更加自由。以前本地通知和遠程推送是分開的,雖然這些到了iOS10都合在一起了,但是為了便于理解,我們還是把他倆分開來進行學習。這節我們學習的是本地通知。 以下的用語,如無特別表述,通知就代表本地通知,推送就...

    快速上手核心動畫

    1、什么是核心動畫 Core Animation是一套包含圖形繪制、投影、動畫的Objective-C類集合,該框架包含在QuartzCore.framework中,它因為被用于處理更為強大的平滑的轉場效果而引入OS X Leopard和iOS而出名。Core Animation和其它框架的位置關系如下圖所示: 核心動畫.png 上圖中的OpenGL ES是個C語言寫的非常底層的圖形處理框架,是個...

    QML進階教程:三、動畫分組(Grouped Animations)

    前言: 如果想同時運行幾個動畫并把他們連接起來,或者在一個一個的運行,或者在兩個動畫之間執行一個腳本。動畫分組 提供了很好的幫助,有兩種方法來分組:平行與連續。可以使用SequentialAnimation(連續動畫) 和ParallelAnimation(平行動畫) 來實現它們,它們作為動畫的容器來包含其它的動畫元素。 代碼實例: 運行軌跡:...

    猜你喜歡

    Animations開源動效分析(一)POP按鈕動畫

    最近Github有一個上很火的開源動畫集叫Animations。 我也很喜歡做動畫動效,特來學習觀摩。因為動效的特殊性,很多情況下這個項目里的動效不能直接Copy到我們現有的項目中直接使用,所以搞清楚她們的實現原理就很有必要了。建議配合源碼學習。 POP按鈕動畫 沒用過的POP的請移步Facebook Pop 使用指南 效果如下 思路 整體效果是用三個CAShapeLayer和一個UILabel組...

    Animations開源動效分析(二)POP-Stroke動畫

    本教程源碼Animations 作者 YouXianMing,建議配合源碼項目食用 Facebook pop動畫框架簡易教程請移步 Facebook Pop 使用指南 CoreAnimation不簡易教程 如果不想看第三條的教程,也要弄明白CALayer的隱式動畫,否則看本文會疑惑,請移步CALayer的隱式動畫和顯式動畫 CAMediaTimingFunction 今天我們來看一下研究一下CAM...

    Flutter Animations showModal 模態動畫方式打開新的頁面

    題記 —— 執劍天涯,從你的點滴積累開始,所及之處,必精益求精,優美的應用體驗 來自于細節的處理,更源自于碼農的自我要求與努力 Flutter是谷歌推出的最新的移動開發框架。 【x1】微信公眾號的每日提醒 隨時隨記 每日積累 隨心而過 文章底部掃碼關注 【x2】各種系列的**** 免費開源 關注 你不會迷路 【x3】系列文章 百萬 Demo 隨時 復制粘貼 使用 【x4】五...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    精品国产乱码久久久久久蜜桃不卡