[Animations] 快速上手 iOS10 屬性動畫
標簽: iOS10 屬性動畫
概述
詳細
基礎動畫, 核心動畫到自定義轉場動畫其實都不是什么新東西了, 所以我也是草草看一遍就能夠讀個大概, 但今天要說的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、文件截圖
注:本文著作權歸作者,由demo大師(http://www.demodashi.com)宣傳,拒絕轉載,轉載需要作者授權
智能推薦
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】五...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...