什么是Layer
?Layer對(duì)象是一種由3D空間組織而成的2D平面,也是Core Animation的核心對(duì)象院溺,類似于View岖妄,Layer管理了幾何圖形的視覺信息,與View不同的是够挂,layer本身并不定義自身的樣子(不會(huì)像button等其它控件一樣有一個(gè)預(yù)定義的樣式),Layer僅僅管理了位圖(bitmap)的狀態(tài)信息锰什,位圖其實(shí)就是UIView等子類在屏幕上所呈現(xiàn)的樣式下硕,也可以把位圖看做是一張圖片丁逝,layer被用來管理這些信息汁胆,所以蘋果把Layer看作是模型對(duì)象(model objects)梭姓。Core Animation就是使用Layer的各種屬性信息,然后將layer的位圖和狀態(tài)信息傳遞給圖形硬件(graphics hardware)嫩码,圖形硬件將使用這些信息來進(jìn)行動(dòng)畫和快速渲染誉尖。
?Layer 與 View的不同主要體現(xiàn)在Layer 不能夠響應(yīng)事件,無法參與到響應(yīng)鏈中铸题,Layer為View的視覺呈現(xiàn)提供了更高效的方式铡恕,Layer是View的基礎(chǔ)設(shè)施。
?默認(rèn)情況下丢间,如果修改Layer中的某個(gè)屬性探熔,Layer的數(shù)據(jù)和狀態(tài)信息會(huì)從該Layer的視覺呈現(xiàn)(位圖)解耦出來,然后交給Core Animation進(jìn)行動(dòng)畫處理烘挫,Core Animation會(huì)通過圖形硬件生成一幀一幀的繪制诀艰,來呈現(xiàn)出動(dòng)畫效果,開發(fā)者只需要指定動(dòng)畫的初始值和終值饮六。
Layer 使用兩種坐標(biāo)系統(tǒng)
?Layer使用基于點(diǎn)的坐標(biāo)系統(tǒng)(point-based coordinate)和單元坐標(biāo)系其垄,基于點(diǎn)的坐標(biāo)系統(tǒng)通常將坐標(biāo)值直接映射到屏幕上(例如position),還有一些屬性是基于其它值卤橄,與屏幕無關(guān)绿满,例如anchorPoint,通過在CGPoint結(jié)構(gòu)體中傳遞0~1之間的值窟扑,用來確定錨點(diǎn)的位置喇颁,該值為相對(duì)于當(dāng)前l(fā)ayer的bounds。在iOS系統(tǒng)中嚎货,坐標(biāo)的起始位置與UIView的坐標(biāo)的起始坐標(biāo)相同无牵,左上角為(0,0)點(diǎn)。
錨點(diǎn): anchorPoint
?幾何相關(guān)的操作都是相對(duì)于layer的錨點(diǎn)進(jìn)行的厂抖,例如position茎毁、rotate、scale等操作忱辅,默認(rèn)情況七蜘,anchorPoint的值為CGPoint(0.5, 0.5),也就是layer的中心位置:
func addLayer() {
let layer = CALayer.init()
let img = UIImage.init(named: "a")
layer.contentsGravity = CALayerContentsGravity.center
layer.contents = img?.cgImage
layer.delegate = self
layer.frame = CGRect.init(x: 0, y: 0, width: 100, height: 100) // 1
layer.borderWidth = 1 / 3
layer.contentsScale = 3
layer.borderColor = UIColor.black.cgColor
self.view.layer.addSublayer(layer)
print(layer.position) //(50.0, 50.0)
print(layer.frame) //(0.0, 0.0, 100.0, 100.0)
}
@IBAction func clickBtn(_ sender: Any) {
let layer = self.view.layer.sublayers!.last!
layer.anchorPoint = CGPoint.init(x: 0, y: 0) // 2
print(layer.position) //(50.0, 50.0)
print(layer.frame) //(50.0, 50.0, 100.0, 100.0)
}
1處代碼指定了layer的frame為(0,0,100,100)墙懂,默認(rèn)的錨點(diǎn)為(0.5,0.5)橡卤,此時(shí)的position為:(50,50),當(dāng)重新設(shè)置了錨點(diǎn)位置2為(0,0)损搬,此時(shí)position沒有變化碧库,但是frame的起始位置變?yōu)?50,50)柜与,可以看到,layer的frame.origin屬性可以由anchorPoint和position確定:
frame.origin.x = position.x - anchorPoint.x * bounds.size.width
frame.origin.y = position.y - anchorPoint.y * bounds.size.height
結(jié)果如下圖所示:
?再來看一下anchorPoint是如何影響旋轉(zhuǎn)的嵌灰,anchorPoint 分別為:(0.5, 0.5) 和(0, 0):
?Layer的anchorPoint屬性會(huì)影響動(dòng)畫的基準(zhǔn)點(diǎn)弄匕,例如旋轉(zhuǎn)時(shí)會(huì)作為中心點(diǎn)。
三種Layer Tree
?Core Animation 有三種類型的Layer:
- model layer tree:就是做動(dòng)畫時(shí)最常使用的layer tree沽瞭,這種類型保存了Core animation進(jìn)行動(dòng)畫的信息迁匠,如果程序需要修改Layer的屬性的話,修改的就是這一類的Layer驹溃。
- Presentation tree:包含了執(zhí)行動(dòng)畫過程中所需要的Layer城丧,雖然這部分Layer也包含了Core Animation執(zhí)行動(dòng)畫時(shí)需要的信息,但是這些數(shù)據(jù)都只是臨時(shí)的豌鹤,不應(yīng)該去修改這部分信息亡哄,但是可以通過 獲取Presetation layer tree的屬性,創(chuàng)建新的動(dòng)畫布疙。
- Render tree蚊惯,這部分layer是用來執(zhí)行動(dòng)畫的,但是是私有的拐辽。
?每一種Layer都是有層級(jí)結(jié)構(gòu)拣挪,類似于views,Layer tree中的每一個(gè)對(duì)象俱诸,都有一個(gè)與之對(duì)應(yīng)的Presentation tree和 Render tree: