Layer和Animation那些事(一)--關系篇

一般開發中常見的是UIView或者它的子類,CALayer似乎并太不常見,最多也就是在倒圓角或者加陰影或者邊框的時候想起它來,但是當有一些復雜動畫或者不尋常視圖顯示需求的時候,亦或是界面卡頓束手無策的時候,你會發現CALayer才是UIView背后視圖顯示處理的真正玩家。

iOS開發常用的視圖控件都是UIView的子類,比如:
UILabel -> UIView
UIImageView -> UIView
UITextView -> UIScrollView -> UIView
UIButton -> UIControl -> UIView
UITextField -> UIControl -> UIView
UISegmentedControl -> UIControl -> UIView
UIView可以處理觸摸事件,可以支持基于Core Graphics繪圖,可以做仿射變換(如旋轉或者縮放),或者簡單的動畫像滑動或者漸變。

UIView是基于CALayer的封裝,目的在于接收觸控事件,除此之外像剛提到的簡單的動畫或者仿射變換其實都是CALayer的能力,UIView只不過是通過對它的Layer層賦值和取值來完成這一操作的,每一個UIView都有一個CALayer實例圖層屬性,這個屬性會和之后添加視圖的實例圖層屬性行成關系樹,用于控制顯示圖層。

此處也可以留意到,其實UIViewCALayer是各司其職的,UIView負責響應鏈的處理,CALayer主要負責視圖顯示的圖層關系和效果的處理,理解這一點,在有一些特殊視圖顯示和響應鏈操作需求的時候會有幫助。蘋果之所以沒有把觸控事件和圖層處理邏輯集中到一個類處理是因為iOS和Mac OS兩個平臺的交互事件不一樣,如果直接設計兩套代碼,那關于圖層部分其實很多是重復的,大部分區別只在于觸控事件不同,所以這樣代碼封裝有利于兩個平臺共享代碼。

  • 布局相關的位置和尺寸的映射
    UIView有三個比較重要的布局屬性:frameboundscenter
    CALayer對應的是:frameboundsposition

我們在操作UIView這三個屬性的時候實際上是操作CALayer對應的三個屬性,所以UIView的三個屬性僅僅是存取方法。所以給CALayer賦能“接收”觸控事件是有性能代價的,由此也可知,如果我們在沒有事件響應需求的時候,是可以通過直接創建并操作CALayer級別的圖層顯示來提升性能的。

frame屬性并不是一個直接屬性或者不是一個真實屬性,它是由boundspositiontransform計算而來的,所以這三個屬性任一個改變都會影響frame,同樣frame改變也會影響它們。

我們熟知的是frame是相對于父視圖坐標尺寸,bounds是相對于自己的坐標尺寸。這樣我們會覺得它們可能只是相對位置坐標不一樣,寬高尺寸是一樣的,其實不然。frame實際上代表了能覆蓋圖層的整個軸對齊的矩形區域,如果視圖旋轉的話,那么frame的寬高和bounds就不一樣了。理解起來有點費勁,來張圖就明白了。

  • 錨點-anchorPoint
    anchorPointCALayer的屬性,并沒有對UIView暴露出來,修改它可以修改圖層的位置,但不改變position。它的取值控件是{0,0}--{1,1}。

  • 坐標系
    UIView身處的二維空間不同,CALayer身處于一個三維空間中,所以它多了一個垂直于屏幕的z坐標軸,相關的兩個屬性為CGFloat類型的zPositionanchorPointZ,一個用于描述圖層在z坐標軸的位置,一個用于描述在z坐標軸方向發生幾何變化時的參照錨點,默認值都是0,也就是所有視圖添加后都在一個平面內。

  • 技術小應用
    這里我們可以假設一個需求:有兩個Button,ButtonA和ButtonB,它們有一部分相交,需求是ButtonA要看起來是在上邊顯示的(如圖),但是點擊到相交的區域要ButtonB來響應。


PlanA:可以從事件響應入手,首先判斷點擊的點的區域是相交的區域,然后攔截父視圖的- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;方法返回ButtonB對象,這樣就可以完成需求效果,但是兩步都比較麻煩。

PlanB:結合前邊的內容,我們知道響應鏈和UIView有關系,顯示層級和CALayer有關系,現在我們首先要保證響應關系,重疊區域的事件響應是按棧管理來處理的,最后添加的最先響應,那么我們首先保證ButtonB是最后添加的,此時ButtonB在重疊區域是在上邊顯示的,那么我要做的就是把ButtonA的視圖層移動到上邊來顯示就可以了,這個時候就用到了CALayerzPosition屬性了,因為默認都是0,所以把ButtonA視圖的CALayer實例屬性的zPosition屬性設置成0.001就OK了,相比PlanA即優雅又簡單。

基于CATextLayer封裝一個控件,在不需要接收觸控事件的時候可以替代UILabel。
demo地址
喜歡就點個贊唄!
歡迎大家提出更好的改進意見和建議,一起進步!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372