1. 概述
上文簡單講述了CALayer的概念以及一些屬性,針對於Layer,除了其展示樣式,我們更注重它的動畫,本篇文章及本專欄的後續文章將圍繞Layer的核心動畫進行探究。
本文首先看一下CALayer的基礎動畫類CABasicAnimation以及CATransaction的使用。
2. CALayer基礎動畫
CALayer基礎動畫類爲CABasicAnimation,看一下官方的定義:
An object that provides basic, single-keyframe animation capabilities for a layer property.
一個能夠給Layer提供基礎的單個關鍵幀動畫能力的對象。
2.1 常用屬性及方法
常用方法及屬性見下表:
屬性及方法 | 類型 | 說明 |
---|---|---|
init(keyPath: String?) |
/ | 初始化方法 |
fromValue |
Any? |
動畫執行初始值 |
toValue |
Any? |
動畫執行結束值 |
byValue |
Any? |
動畫執行的結束值與初始值的差值 |
keyPath |
String? |
指定執行動畫的key path |
isRemovedOnCompletion |
Bool |
動畫執行結束後是否從目標圖層中移除。設置爲false解決動畫恢復到初始位置的問題。 |
fillMode |
CAMediaTimingFillMode |
removed:默認值,動畫開始前和結束後,動畫對圖層都沒有影響,圖層依然保持初始值。 forwards:動畫結束後保持最終的可見狀態。 backwards:動畫開始前,只要加入動畫,圖層就會處於動畫的初始狀態,即第一幀動畫。 both:綜合了forwards和backwards兩種功能,動畫加入圖層到真正執行動畫的時間段裏,圖層保持動畫初始狀態;動畫結束之後保持動畫最終狀態 |
duration |
CFTimeInterval |
動畫執行時長 |
repeatCount |
Float |
動畫執行次數 |
repeatDuration |
CFTimeInterval |
動畫多久後執行一次。 |
創建動畫的時候可通過init(keyPath: String?)方法實例化一個對象,並指定一個屬性的keyPath用於動畫。
可以將一個標量屬性(有具體的數值)添加動畫,比如不同明度(opacity),將其值從0設置到1,代碼如下:
override func viewDidLoad() {
super.viewDidLoad()
layer.frame = CGRect(x: 20, y: 60, width: 100, height: 100)
layer.backgroundColor = UIColor.red.cgColor
self.view.layer.addSublayer(layer)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2
animation.isRemovedOnCompletion = false
animation.fillMode = .forwards
layer.add(animation, forKey: nil)
}
上面創建了一個紅色的layer,並將其添加到了當前view的layer中,當點擊屏幕的時候,修改紅色layer的opacity。
一些非標量屬性,比如背景色(backgroundColor),其值變化也可以加入動畫,代碼如下,重複代碼不在提現:
let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.toValue = UIColor.blue.cgColor
還給可給一些多值的屬性添加動畫,比如位置信息(position),代碼如下:
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = [0, 0]
animation.toValue = [100, 100]
除了以上,還可以給某個屬性的裏面的某個值添加動畫,例如:
let animation = CABasicAnimation(keyPath: "transform.scale.x")
animation.fromValue = 1
animation.toValue = 2
2.2 常用Key Paths
以上便是一些基礎動畫的創建,至於哪些keyPath可以執行動畫,具體如下:
CATransform3D Key Paths
Key Path |
Description |
---|---|
transform. |
設置一個沿着x軸旋轉的弧度值。 關於π,Swift 3.0以後請使用Doubl.pi |
transform. |
設置一個沿着y軸旋轉的弧度值。 |
transform. |
設置一個沿着z軸旋轉的弧度值。 |
transform. |
設置一個沿着z軸旋轉的弧度值,同transform. |
transform. |
設置一個沿着x軸放縮的比例因子。 |
transform. |
設置一個沿着y軸放縮的比例因子。 |
transform. |
設置一個沿着z軸放縮的比例因子。 |
transform. |
設置一個整體放縮的比例因子。 |
transform. |
設置一個沿着x軸移動的值。 |
transform. |
設置一個沿着y軸移動的值。 |
transform. |
設置一個沿着z軸移動的值。 |
transform.translation |
設置一個結構體類型的值,例如CGSize,CGPoint,其值表示沿着x軸和y軸移動的數值。 |
CGPoint Key Paths
Key Path |
Description |
---|---|
position. |
設置一箇中心點沿着x軸移動的值。 |
position. |
設置一箇中心點沿着y軸移動的值。 |
CGSize Key Paths
Key Path | Description |
---|---|
|
設置一個寬度變換的值。 |
|
設置一個高度變換的值。 |
3. CATransaction
CATransaction是將Layer tree多個操作批處理爲渲染樹的原子更新的核心動畫機制。對Layer tree的每個修改都必須是CATransaction的一部分。支持嵌套CATransaction。
Core Animation支持兩種類型的CATransaction:implicit transactions(隱式)和explicit transactions(顯式)。
implicit transactions在沒有活動transactions的線程修改layer tree的時候自動創建,並在線程runloop下一次迭代的時候自動提交。
explicit transactions則是在修改layer tree之前向CATransaction類發送begin()消息,修改後發送commit()消息時時候觸發。
常用類方法如下表:
類方法 | 說明 |
---|---|
class func begin() |
在當前線程創建一個transaction。 |
class func commit() |
提交當前transaction的所有修改。 |
class func flush() |
刷新任何存在的隱式transaction. |
class func animationDuration() -> CFTimeInterval |
返回在transaction組中所有動畫的執行時間。 |
class func setAnimationDuration(CFTimeInterval) |
設置transaction組中所有動畫的執行時間。 |
class func completionBlock() -> (() -> Void)? |
返回動畫結束後的block對象。 |
class func setCompletionBlock((() -> Void)?) |
設置動畫結束後的block對象。 |
關於隱式動畫,我們不需要添加額外的代碼,系統會自己處理,比如在改變backgroundColor的時候,顏色會從一個到另一個顏色漸變過去,系統的動畫時間爲0.25秒。
至於顯示動畫,則需要我們手動添加代碼了。
先看一段簡單的代碼,將一個Layer的的size變成原來的兩倍,並改變其背景色。
func transactionAnimation() {
CATransaction.begin()
let transform = CATransform3DScale(layer.transform, 2, 2, 2)
layer.transform = transform
CATransaction.setAnimationDuration(2)
CATransaction.setCompletionBlock {
self.layer.backgroundColor = UIColor.blue.cgColor
}
CATransaction.commit()
}
下面看一個顯示的嵌套CATransaction,Layer從不透明到透明,然後移除,期間size變爲原來的3倍。
func transactionNestedAnimation() {
// Outer transaction animates `opacity` to 0 over 2 seconds
CATransaction.begin()
CATransaction.setAnimationDuration(2)
layer.opacity = 0
CATransaction.setCompletionBlock {
self.layer.removeFromSuperlayer()
}
// Inner transaction animates scale to (3, 3, 3) over 1 second
CATransaction.begin()
CATransaction.setAnimationDuration(2)
layer.transform = CATransform3DMakeScale(3, 3, 3)
CATransaction.commit() // Commits inner transaction
CATransaction.commit() // Commits outer transaction
}
4. 總結
本文主要講述了CABasicAnimation以及CATransaction兩種動畫,作爲基礎動畫,用起來並不難,文中也列舉了常用的一些方法和屬性等。
文中如有不正確的地方,還請路過的朋友指正。
本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需轉載,請標明出處。