CATransaction是 Core Animation 中的事務類,在iOS中的圖層中,圖層的每個改變都是事務的一部分,CATransaction可以對多個layer的屬性同時進行修改,同時負責成批的把多個圖層樹的修改作為一個原子更新到渲染樹。
/* CoreAnimation - CATransaction.h
Copyright (c) 2006-2016, Apple Inc.
All rights reserved. */`
/* Transactions are CoreAnimation's mechanism for batching multiple layer-
* tree operations into atomic updates to the render tree. Every
* modification to the layer tree requires a transaction to be part of.
*
* CoreAnimation supports two kinds of transactions, "explicit" transactions
* and "implicit" transactions.
*
* Explicit transactions are where the programmer calls `[CATransaction
* begin]' before modifying the layer tree, and `[CATransaction commit]'
* afterwards.
*
* Implicit transactions are created automatically by CoreAnimation when the
* layer tree is modified by a thread without an active transaction.
* They are committed automatically when the thread's run-loop next
* iterates. In some circumstances (i.e. no run-loop, or the run-loop
* is blocked) it may be necessary to use explicit transactions to get
* timely render tree updates. */
@available(iOS 2.0, *)
open class CATransaction : NSObject
CATransaction事務類分為隱式事務和顯式事務,注意以下兩組概念的區分:
1.隱式動畫和隱式事務:
隱式動畫通過隱式事務實現動畫 。
2.顯式動畫和顯式事務:
顯式動畫有多種實現方式,顯式事務是一種實現顯式動畫的方式。
一、隱式事務
除顯式事務外,任何對于CALayer屬性的修改,都是隱式事務.這樣的事務會在run-loop中被提交.
當圖層樹被沒有獲得事務的線程修改的時候將會自動創建隱式事務,當線程的運行循環(run-loop)執行下次迭代的時候將會自動提交事務。 但是,當在同一個運行循環(runloop)的線程修改圖層的屬性時,你必須使用顯式事務。以下皆是隱式事務。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
layer = CALayer()
layer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
layer.position = CGPoint.init(x: 150, y: 100)
layer.backgroundColor = UIColor.red.cgColor
layer.borderColor = UIColor.black.cgColor
layer.opacity = 1.0
self.view.layer.addSublayer(layer)
}
可以通過下面的方法查看動畫的效果,前提是讓動畫效果出來:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// 設置變化動畫過程是否顯示,默認為true不顯示
CATransaction.setDisableActions(false)
// 設置圓角
layer.cornerRadius = (layer.cornerRadius == 0.0) ? 30.0 : 0.0
// 設置透明度
layer.opacity = (layer.opacity == 1.0) ? 0.5 : 1.0
}
二、顯式事務
在你修改圖層樹之前,可以通過給 CATransaction 類發送一個 begin 消息來創建一個顯式事務,修改完成之后發送 comit 消息。顯式事務在同時設置多個圖層的屬性的時候(例如當布局多個圖層的時候),暫時的禁用圖層的行為,或者暫時修改動畫的時間的時候非常有用 。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// 開啟事務
CATransaction.begin()
// 顯式事務默認開啟動畫效果,kCFBooleanTrue關閉
CATransaction.setValue(kCFBooleanFalse, forKey: kCATransactionDisableActions)
// 動畫執行時間
CATransaction.setValue(5.0, forKey: kCATransactionAnimationDuration)
layer.cornerRadius = (layer.cornerRadius == 0.0) ? 30.0 : 0.0
layer.opacity = (layer.opacity == 1.0) ? 0.5 : 1.0
// 提交事務
CATransaction.commit()
}