iOS UIView和CALayer

在 iOS 中,所有的 view 都是由一個(gè)底層的 layer 來(lái)驅(qū)動(dòng)的绊汹。view 和它的 layer 之間有著緊密的聯(lián)系,view 其實(shí)直接從 layer 對(duì)象中獲取了絕大多數(shù)它所需要的數(shù)據(jù)扮宠。layer側(cè)重于圖形的顯示西乖,而view相當(dāng)于layer的管理者。CALayer屬于QuartzCore框架,用于在iOS和Mac OS系統(tǒng)上可見(jiàn)元素的繪制,和屬于UIKit框架的UIView的關(guān)系是,UIView默認(rèn)會(huì)創(chuàng)建一個(gè)CALayer屬性,用于圖象的繪制和顯示.CALayer也可以單獨(dú)創(chuàng)建坛增。

1.首先UIView可以響應(yīng)事件获雕,Layer不可以.

UIKit使用UIResponder作為響應(yīng)對(duì)象,來(lái)響應(yīng)系統(tǒng)傳遞過(guò)來(lái)的事件并進(jìn)行處理收捣。UIApplication届案、UIViewController、UIView罢艾、和所有從UIView派生出來(lái)的UIKit類(lèi)(包括UIWindow)都直接或間接地繼承自UIResponder類(lèi)楣颠。

在 UIResponder中定義了處理各種事件和事件傳遞的接口, 而 CALayer直接繼承 NSObject,并沒(méi)有相應(yīng)的處理事件的接口咐蚯。

2.View和CALayer的Frame映射及View如何創(chuàng)建CALayer.

一個(gè) Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform(圖層旋轉(zhuǎn)) 共同決定的

布局

要分析CALayer的anchorPoint和position屬性,首先要討論一下CALayer的布局.

我們所熟悉的UIView有三個(gè)重要的布局屬性:frame,bounds和center,CALayer對(duì)應(yīng)的叫做frame,bounds和position.

frame:代表了圖層的外部坐標(biāo)(在父圖層上占據(jù)的空間)

bounds:為內(nèi)部坐標(biāo)

position:代表了相對(duì)父圖層anchorPoint的位置

錨點(diǎn)

如何理解anchorPoint(錨點(diǎn))?

和position共同決定圖層相對(duì)父圖層的位置,即frame的x,y

在圖層旋轉(zhuǎn)時(shí)的固定點(diǎn)

錨點(diǎn)使用單位坐標(biāo)來(lái)描述,范圍為左上角{0, 0}到右下角{1, 1},默認(rèn)坐標(biāo)是{0.5, 0.5}.

錨點(diǎn)和position的關(guān)系

position是圖層的anchorPoint在父圖層中的位置坐標(biāo).

anchorPoint和position共同決定圖層相對(duì)父圖層的位置,即frame屬性的frame.origin.

單方面修改anchorPoint或者position并不會(huì)對(duì)彼此產(chǎn)生影響,修改其中一個(gè)值,受影響的只會(huì)是frame.origin.

圖層旋轉(zhuǎn)時(shí),如何修改錨點(diǎn)

在圖層旋轉(zhuǎn)時(shí),錨點(diǎn)就是圖層的固定點(diǎn),旋轉(zhuǎn)是沿著這個(gè)定點(diǎn)進(jìn)行的.(表盤(pán)布局demo)

單方面修改anchorPoint或者position并不會(huì)對(duì)彼此產(chǎn)生影響,修改其中一個(gè)值,受影響的只會(huì)是frame.origin.

anchorPoint和position共同決定了frame

frame.origin.x = position.x - anchorPoint.x * bounds.size.width童漩;

frame.origin.y = position.y - anchorPoint.y * bounds.size.height

anchorPoint是圖層在旋轉(zhuǎn)時(shí)的固定點(diǎn)

一個(gè) View 的 frame 只是簡(jiǎn)單的返回 Layer的 frame,View 的 Center 和 Bounds 只是直接返回layer 對(duì)應(yīng)的 Position 和 Bounds.

[UIView?_createLayerWithFrame]

[Layer?setBounds:bounds]

[UIView?setFrame:Frame]

[Layer?setFrame:frame]

[Layer?setPosition:position]

[Layer?setBounds:bounds]

View中frame getter方法春锋,bounds和center矫膨,UIView并沒(méi)有做什么工作;它只是簡(jiǎn)單的各自調(diào)用它底層的CALayer的frame期奔,bounds和position方法侧馅。

3.UIView主要是對(duì)顯示內(nèi)容的管理而 CALayer 主要側(cè)重顯示內(nèi)容的繪制。

分別重寫(xiě)UIView 和 CALayer?父類(lèi)的方法:

[UIView?drawRect:rect]//UIView????

[CALayer?display]//CALayer

UIView 是 CALayer 的CALayerDelegate呐萌,在代理方法內(nèi)部[UIView(CALayerDelegate) drawLayer:inContext]調(diào)用 UIView 的 DrawRect方法馁痴,從而繪制出了 UIView 的內(nèi)容。

4.在做 iOS 動(dòng)畫(huà)的時(shí)候搁胆,修改非 RootLayer的屬性(譬如位置弥搞、背景色等)會(huì)默認(rèn)產(chǎn)生隱式動(dòng)畫(huà),而修改UIView則不會(huì)渠旁。

對(duì)于每一個(gè) UIView 都有一個(gè) layer,把這個(gè) layer 且稱作RootLayer,而不是 View 的根 Layer的叫做 非 RootLayer攀例。我們對(duì)UIView的屬性修改時(shí)時(shí)不會(huì)產(chǎn)生默認(rèn)動(dòng)畫(huà),而對(duì)單獨(dú) layer屬性直接修改會(huì)顾腊,這個(gè)默認(rèn)動(dòng)畫(huà)的時(shí)間缺省值是0.25s.

在 Core Animation 編程指南的 “How to Animate Layer-Backed Views” 中粤铭,對(duì)為什么會(huì)這樣做出了一個(gè)解釋?zhuān)?/p>

UIView 默認(rèn)情況下禁止了 layer 動(dòng)畫(huà),但是在 animation block 中又重新啟用了它們

是因?yàn)槿魏慰蓜?dòng)畫(huà)的 layer 屬性改變時(shí)杂靶,layer 都會(huì)尋找并運(yùn)行合適的 'action' 來(lái)實(shí)行這個(gè)改變梆惯。在 Core Animation 的專(zhuān)業(yè)術(shù)語(yǔ)中就把這樣的動(dòng)畫(huà)統(tǒng)稱為動(dòng)作 (action酱鸭,或者 CAAction)。

layer 通過(guò)向它的 delegate 發(fā)送 actionForLayer:forKey: 消息來(lái)詢問(wèn)提供一個(gè)對(duì)應(yīng)屬性變化的 action垛吗。delegate 可以通過(guò)返回以下三者之一來(lái)進(jìn)行響應(yīng):

它可以返回一個(gè)動(dòng)作對(duì)象凹髓,這種情況下 layer 將使用這個(gè)動(dòng)作。

它可以返回一個(gè) nil怯屉, 這樣 layer 就會(huì)到其他地方繼續(xù)尋找蔚舀。

它可以返回一個(gè) NSNull 對(duì)象,告訴 layer 這里不需要執(zhí)行一個(gè)動(dòng)作锨络,搜索也會(huì)就此停止赌躺。

當(dāng) layer 在背后支持一個(gè) view 的時(shí)候,view 就是它的 delegate羡儿;

總結(jié)

總接來(lái)說(shuō)就是如下幾點(diǎn):

每個(gè) UIView 內(nèi)部都有一個(gè) CALayer 在背后提供內(nèi)容的繪制和顯示礼患,并且 UIView 的尺寸樣式都由內(nèi)部的 Layer 所提供。兩者都有樹(shù)狀層級(jí)結(jié)構(gòu)掠归,layer 內(nèi)部有 SubLayers缅叠,View 內(nèi)部有 SubViews.但是 Layer 比 View 多了個(gè)AnchorPoint

在 View顯示的時(shí)候,UIView 做為 Layer 的 CALayerDelegate,View 的顯示內(nèi)容由內(nèi)部的 CALayer 的 display

CALayer 是默認(rèn)修改屬性支持隱式動(dòng)畫(huà)的拂到,在給 UIView 的 Layer 做動(dòng)畫(huà)的時(shí)候痪署,View 作為 Layer 的代理,Layer 通過(guò) actionForLayer:forKey:向 View請(qǐng)求相應(yīng)的 action(動(dòng)畫(huà)行為)

layer 內(nèi)部維護(hù)著三分 layer tree,分別是 presentLayer Tree(動(dòng)畫(huà)樹(shù)),modelLayer Tree(模型樹(shù)), Render Tree (渲染樹(shù)),在做 iOS動(dòng)畫(huà)的時(shí)候兄旬,我們修改動(dòng)畫(huà)的屬性狼犯,在動(dòng)畫(huà)的其實(shí)是 Layer 的 presentLayer的屬性值,而最終展示在界面上的其實(shí)是提供 View的modelLayer

兩者最明顯的區(qū)別是 View可以接受并處理事件,而 Layer 不可以领铐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悯森,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绪撵,更是在濱河造成了極大的恐慌瓢姻,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件音诈,死亡現(xiàn)場(chǎng)離奇詭異幻碱,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)细溅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)褥傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人喇聊,你說(shuō)我怎么就攤上這事恍风。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵朋贬,是天一觀的道長(zhǎng)凯楔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)锦募,這世上最難降的妖魔是什么摆屯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮御滩,結(jié)果婚禮上鸥拧,老公的妹妹穿的比我還像新娘党远。我一直安慰自己削解,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布沟娱。 她就那樣靜靜地躺著氛驮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪济似。 梳的紋絲不亂的頭發(fā)上矫废,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音砰蠢,去河邊找鬼蓖扑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛台舱,可吹牛的內(nèi)容都是我干的律杠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼竞惋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柜去!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拆宛,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嗓奢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后浑厚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體股耽,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年钳幅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了物蝙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贡这,死狀恐怖茬末,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤丽惭,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布击奶,位于F島的核電站,受9級(jí)特大地震影響责掏,放射性物質(zhì)發(fā)生泄漏柜砾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一换衬、第九天 我趴在偏房一處隱蔽的房頂上張望痰驱。 院中可真熱鬧,春花似錦瞳浦、人聲如沸担映。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蝇完。三九已至,卻和暖如春矗蕊,著一層夾襖步出監(jiān)牢的瞬間短蜕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工傻咖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朋魔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓卿操,卻偏偏與公主長(zhǎng)得像警检,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子硬纤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349