詳解CALayer 和 UIView的區(qū)別和聯(lián)系

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

UIKit使用UIResponder作為響應(yīng)對(duì)象,來響應(yīng)系統(tǒng)傳遞過來的事件并進(jìn)行處理。UIApplication壹瘟、UIViewController其障、UIView银室、和所有從UIView派生出來的UIKit類(包括UIWindow)都直接或間接地繼承自UIResponder類。

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

下面列舉一些處理觸摸事件的接口

  • – touchesBegan:withEvent:
  • – touchesMoved:withEvent:
  • – touchesEnded:withEvent:
  • – touchesCancelled:withEvent:
    其實(shí)還有一些運(yùn)動(dòng)和遠(yuǎn)程控制事件等等,這里就不一一列舉了汽抚。

下面的兩篇文章詳細(xì)介紹了 iOS 事件的處理和傳遞
參考鏈接
http://blog.csdn.net/chun799/article/details/8223612
http://yishuiliunian.gitbooks.io/implementate-tableview-to-understand-ios/content/uikit/1-1-2.html

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

一個(gè) Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同決定的抓狭,而一個(gè) View 的 frame 只是簡(jiǎn)單的返回 Layer的 frame,同樣 View 的 center和 bounds 也是返回 Layer 的一些屬性造烁。(PS:center有些特列)為了證明這些否过,我做了如下的測(cè)試。

首先我自定義了兩個(gè)類CustomView,CustomLayer分別繼承 UIView 和 CALayer

在 CustomView 中重寫了

+ (Class)layerClass
{
    return [CustomLayer class];
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
}

- (void)setCenter:(CGPoint)center
{
    [super setCenter:center];
}

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
}

同樣在 CustomLayer中同樣重寫這些方法惭蟋。只是setCenter
方法改成setPosition方法

我在兩個(gè)類的初始化方法中都打下了斷點(diǎn)

Snip20150820_12.png

首先我們會(huì)發(fā)現(xiàn)苗桂,我們?cè)?[view initWithFrame] 的時(shí)候調(diào)用私有方法【UIView _createLayerWithFrame】去創(chuàng)建 CALayer。
然后我在創(chuàng)建 View 的時(shí)候告组,在 Layer 和 View 中Frame 相關(guān)的所有方法中都加上斷點(diǎn)煤伟,可以看到大致如下的調(diào)用順序如下

[UIView _createLayerWithFrame]
[Layer setBounds:bounds]
[UIView setFrame:Frame]
[Layer setFrame:frame]
[Layer setPosition:position]
[Layer setBounds:bounds]

我發(fā)現(xiàn)在創(chuàng)建的過程只有調(diào)用了 Layer 的設(shè)置尺寸和位置的然而并沒有調(diào)用View 的SetCenter
SetBounds
方法。然后我發(fā)現(xiàn)當(dāng)我修改了 view的bounds.size
或者bounds.origin
的時(shí)候也只會(huì)調(diào)用上邊 Layer的一些方法木缝。所以我大膽的猜一下便锨,View 的 Center 和 Bounds 只是直接返回layer 對(duì)應(yīng)的 Position 和 Bounds.
View中frame getter方法,bounds和center我碟,UIView并沒有做什么工作放案;它只是簡(jiǎn)單的各自調(diào)用它底層的CALayer的frame,bounds和position方法怎囚。
關(guān)于 Frame 的理解參考:http://www.cocoachina.com/industry/20131209/7498.html

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

我在 UIView 和 CALayer 分別重寫了父類的方法桥胞。
[UIView drawRect:rect]//UIView [CALayer display]//CALayer

然后我在上面兩個(gè)方法加了斷點(diǎn),可以看到如下的執(zhí)行考婴。


image

可以看到 UIView 是 CALayer 的CALayerDelegate贩虾,我猜測(cè)是在代理方法內(nèi)部[UIView(CALayerDelegate) drawLayer:inContext]調(diào)用 UIView 的 DrawRect方法,從而繪制出了 UIView 的內(nèi)容.

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

對(duì)于每一個(gè) UIView 都有一個(gè) layer,把這個(gè) layer 且稱作RootLayer,而不是 View 的根 Layer的叫做 非 RootLayer策精。我們對(duì)UIView的屬性修改時(shí)時(shí)不會(huì)產(chǎn)生默認(rèn)動(dòng)畫,而對(duì)單獨(dú) layer屬性直接修改會(huì)崇棠,這個(gè)默認(rèn)動(dòng)畫的時(shí)間缺省值是0.25s.在 Core Animation 編程指南的 “How to Animate Layer-Backed Views” 中咽袜,對(duì)為什么會(huì)這樣做出了一個(gè)解釋:

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

是因?yàn)槿魏慰蓜?dòng)畫的 layer 屬性改變時(shí)枕稀,layer 都會(huì)尋找并運(yùn)行合適的 'action' 來實(shí)行這個(gè)改變询刹。在 Core Animation 的專業(yè)術(shù)語中就把這樣的動(dòng)畫統(tǒng)稱為動(dòng)作 (action,或者 CAAction)萎坷。
layer 通過向它的 delegate 發(fā)送 actionForLayer:forKey: 消息來詢問提供一個(gè)對(duì)應(yīng)屬性變化的 action凹联。delegate 可以通過返回以下三者之一來進(jìn)行響應(yīng):
1.它可以返回一個(gè)動(dòng)作對(duì)象,這種情況下 layer 將使用這個(gè)動(dòng)作哆档。
2.它可以返回一個(gè) nil蔽挠, 這樣 layer 就會(huì)到其他地方繼續(xù)尋找。
3.它可以返回一個(gè) NSNull 對(duì)象瓜浸,告訴 layer 這里不需要執(zhí)行一個(gè)動(dòng)作澳淑,搜索也會(huì)就此停止。

當(dāng) layer 在背后支持一個(gè) view 的時(shí)候斟叼,view 就是它的 delegate偶惠;
這部分的具體內(nèi)容參考:http://objccn.io/issue-12-4/

總結(jié)

總接來說就是如下幾點(diǎn):

  • 每個(gè) UIView 內(nèi)部都有一個(gè) CALayer 在背后提供內(nèi)容的繪制和顯示,并且 UIView 的尺寸樣式都由內(nèi)部的 Layer 所提供朗涩。兩者都有樹狀層級(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)畫的兄一,在給 UIView 的 Layer 做動(dòng)畫的時(shí)候,View 作為 Layer 的代理识腿,Layer 通過 actionForLayer:forKey:向 View請(qǐng)求相應(yīng)的 action(動(dòng)畫行為)
  • layer 內(nèi)部維護(hù)著三分 layer tree,分別是 presentLayer Tree(動(dòng)畫樹),modeLayer Tree(模型樹), Render Tree (渲染樹),在做 iOS動(dòng)畫的時(shí)候出革,我們修改動(dòng)畫的屬性,在動(dòng)畫的其實(shí)是 Layer 的 presentLayer的屬性值,而最終展示在界面上的其實(shí)是提供 View的modelLayer
  • 兩者最明顯的區(qū)別是 View可以接受并處理事件渡讼,而 Layer 不可以
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骂束,一起剝皮案震驚了整個(gè)濱河市耳璧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌展箱,老刑警劉巖旨枯,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異混驰,居然都是意外死亡攀隔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門栖榨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昆汹,“玉大人,你說我怎么就攤上這事婴栽÷郑” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵居夹,是天一觀的道長败潦。 經(jīng)常有香客問我,道長准脂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任檬洞,我火速辦了婚禮狸膏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘添怔。我一直安慰自己湾戳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布广料。 她就那樣靜靜地躺著砾脑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艾杏。 梳的紋絲不亂的頭發(fā)上韧衣,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音购桑,去河邊找鬼畅铭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛勃蜘,可吹牛的內(nèi)容都是我干的硕噩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼缭贡,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼炉擅!你這毒婦竟也來了辉懒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤谍失,失蹤者是張志新(化名)和其女友劉穎耗帕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袱贮,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仿便,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了攒巍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗽仪。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柒莉,靈堂內(nèi)的尸體忽然破棺而出闻坚,到底是詐尸還是另有隱情,我是刑警寧澤兢孝,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布窿凤,位于F島的核電站,受9級(jí)特大地震影響跨蟹,放射性物質(zhì)發(fā)生泄漏雳殊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一窗轩、第九天 我趴在偏房一處隱蔽的房頂上張望夯秃。 院中可真熱鬧,春花似錦痢艺、人聲如沸仓洼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽色建。三九已至,卻和暖如春舌缤,著一層夾襖步出監(jiān)牢的瞬間箕戳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工友驮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漂羊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓卸留,卻偏偏與公主長得像走越,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耻瑟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 前言 前面發(fā)了一篇iOS 面試的文章旨指,在說到 UIView 和 CALayer 的區(qū)別和聯(lián)系的時(shí)候赏酥,被喵神指出沒有...
    kissGod閱讀 57,179評(píng)論 23 268
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜谆构,今天將帶大家一窺ios動(dòng)畫全貌裸扶。在這里你可以看...
    每天刷兩次牙閱讀 8,485評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜搬素,今天將帶大家一窺iOS動(dòng)畫全貌呵晨。在這里你可以看...
    F麥子閱讀 5,110評(píng)論 5 13
  • 1.首先UIView可以響應(yīng)事件,Layer不可以. UIKit使用UIResponder作為響應(yīng)對(duì)象熬尺,來響應(yīng)系統(tǒng)...
    Crazy2015閱讀 853評(píng)論 0 0
  • 前言 前面發(fā)了一篇iOS 面試的文章摸屠,在說到 UIView 和 CALayer 的區(qū)別和聯(lián)系的時(shí)候,被喵神指出沒有...
    Mz楓閱讀 758評(píng)論 0 4