UIView與CALayer的區別,很詳細

研究Core Animation已經有段時間了,關於Core Animation,網上沒什麼好的介紹。蘋果網站上有篇專門的總結性介紹,可是彷佛原理性的東西很少,看得人云山霧罩,感受,寫那篇東西的人,實際上是假設讀的人瞭解界面動畫技術的原理的。今天有點別的事情要使用Linux,忘掉了ssh的密碼,沒辦法從新設ssh,結果怎麼也想不起來怎麼設ssh遠程登錄了,沒辦法又到網上查了一遍,太浪費時間了,痛感忘記記筆記是多麼可怕的事情。鑑於Core Animation的內容實在是很是繁雜,應用的Obj-C語言自己的特性也不少,因此寫個備忘錄記錄一下,懂的人看了後若是發現了錯誤,還不吝指教。

1.UIView是iOS系統中界面元素的基礎,全部的界面元素都繼承自它。它自己徹底是由CoreAnimation來實現的(Mac下彷佛不是這樣)。它真正的繪圖部分,是由一個叫CALayer(Core Animation Layer)的類來管理。UIView自己,更像是一個CALayer的管理器,訪問它的跟繪圖和跟座標有關的屬性,例如frame,bounds等等,實際上內部都是在訪問它所包含的CALayer的相關屬性。

2.UIView有個layer屬性,能夠返回它的主CALayer實例,UIView有一個layerClass方法,返回主layer所使用的類,UIView的子類,能夠經過重載這個方法,來讓UIView使用不一樣的CALayer來顯示,例如經過
1
- (class) layerClass {
2
  return ([CAEAGLLayer class]);
3
}
使某個UIView的子類使用GL來進行繪製。

3.UIView的CALayer相似UIView的子View樹形結構,也能夠向它的layer上添加子layer,來完成某些特殊的表示。例以下面的代碼
1
grayCover = [[CALayer alloc] init];
2
grayCover.backgroundColor = [[[UIColor blackColor] colorWithAlphaComponent:0.2] CGColor];
3
[self.layer addSubLayer: grayCover];
會在目標View上敷上一層黑色的透明薄膜。

4.UIView的layer樹形在系統內部,被系統維護着三份copy(這段理解有點吃不許)。
第一份,邏輯樹,就是代碼裏能夠操縱的,例如更改layer的屬性等等就在這一份。
第二份,動畫樹,這是一箇中間層,系統正在這一層上更改屬性,進行各類渲染操做。
第三份,顯示樹,這棵樹的內容是當前正被顯示在屏幕上的內容。
這三棵樹的邏輯結構都是同樣的,區別只有各自的屬性。

5.動畫的運做
UIView的主layer之外(我以爲是這樣),對它的subLayer,也就是子layer的屬性進行更改,系統將自動進行動畫生成,動畫持續時間有個缺省時間,我的感受大概是0.5秒。在動畫時間裏,系統自動斷定哪些屬性更改了,自動對更改的屬性進行動畫插值,生成中間幀而後連續顯示產生動畫效果。

6.座標系系統(對position和anchorPoint的關係仍是犯暈)
CALayer的座標系系統和UIView有點不同,它多了一個叫anchorPoint的屬性,它使用CGPoint結構,可是值域是0~1,也就是按照比例來設置。這個點是各類圖形變換的座標原點,同時會更改layer的position的位置,它的缺省值是{0.5, 0.5},也就是在layer的中央。
某layer.anchorPoint = CGPointMake(0.f, 0.f);
若是這麼設置,layer的左上角就會被挪到原來的中間的位置,
加上這樣一句就行了
某layer.position = CGPointMake(0.f, 0.f);

7.真實例子的分析

   
這是iphone上iBook翻頁的效果,假設每一頁都是一個UIView,我以爲一個頁面是貼了倆個Layer,文字Layer顯示正面的內容,背面layer用文字layer的快照作affine翻轉,貼在文字layer的後面。由於Layer能夠設置顯示陰影,也許後面的陰影效果沒有使用單獨的一個layer來顯示。至於這個曲面效果,我查了不少資料也沒有結果,估計是使用了GL的曲面繪圖?

8.最後一個讓人噁心的。

layer能夠設置圓角顯示,例如UIButton的效果,也能夠設置陰影顯示,可是若是layer樹中的某個layer設置了圓角,樹中全部layer的陰影效果都將顯示不了了。若是既想有圓角又想要陰影,好像只能作兩個重疊的UIView,一個的layer顯示圓角,一個的layer顯示陰影..... windows


1)老祖 app

萬物歸根,UIView和CALayer都是的老祖都是NSObjet。 框架

 

1: UIView的繼承結構爲: UIResponder : NSObjectiview

 

能夠看出UIView的直接父類爲UIResponder 類, UIResponder 是gsm的呢? ssh

官方的解釋: iphone

The UIResponder class defines an interface for objects that respond to and handle events. It is the superclass of UIApplicationUIView and its subclasses (which include UIWindow). Instances of these classes are sometimes referred to as responder objects or, simply, responders. ide

 

The UIView class defines a rectangular area on the screen and the interfaces for managing the content in that area. At runtime, a view object handles the rendering of any content in its area and also handles any interactions with that content. The UIView class itself provides basic behavior for filling its rectangular area with a background color. More sophisticated content can be presented by subclassing UIView and implementing the necessary drawing and event-handling code yourself. The UIKit framework also includes a set of standard subclasses that range from simple buttons to complex tables and can be used as-is. For example, a UILabelobject draws a text string and a UIImageView object draws an image. 佈局

 

可見 UIResponder是用來響應事件的,也就是UIView能夠響應用戶事件。 動畫

 

2:CALayer的繼承結構爲: NSObject 網站

 

直接從 NSObject繼承,由於缺乏了UIResponder類,因此CALayer悲催的不能響應任何用戶事件。

 

The CALayer class is the model class for layer-tree objects. It encapsulates the position, size, and transform of a layer, which defines its coordinate system. It also encapsulates the duration and pacing of a layer and its animations by adopting the CAMediaTiming protocol, which defines a layer’s time space.

 

從官方的解釋能夠看出,CALayer定義了position、size、transform、animations 等基本屬性。那UIView的size、frame、position這些屬性是從那裏來的呢?上面的官方解釋沒有說明這一點,咱們一會再分析

 

至此咱們瞭解到了,UIView 和CALayer的基本信息和主要負責處理的事情。

 

(2)所屬框架

1:UIView是在 /System/Library/Frameworks/UIKit.framework中定義的。

這個又是作什麼的呢?

The UIKit framework provides the classes needed to construct and manage an application’s user interface for iOS. It provides an application object, event handling, drawing model, windows, views, and controls specifically designed for a touch screen interface.

 

可見UIKit主要是用來構建用戶界面,而且是能夠響應事件的(得意與UIView的父類UIResponder,至於UIResponderd的實現原理不是此次分析的目的,在此不作過多的解釋

 

在這裏思考一個問題UIView既然是構建用戶界面的,那他是經過什麼方式繪製這些圖片、文字之類的信息的呢? 

 

Ios中的2D圖像繪製都是經過QuartzCore.framework實現的。難道是經過QuartzCore.framework實現的?那又是經過什麼方式和QuartzCore.framework聯繫起來的呢??咱們一會再看。

 

2:CALayer是在/System/Library/Frameworks/QuartzCore.framework定義的。並且CALayer做爲一個低級的,能夠承載繪製內容的底層對象出如今該框架中。

 

 

如今比較一下uiview和calayer均可以顯示圖片文字等信息。難道apple提供了,兩套繪圖機制嗎?不會。

UIView相比CALayer最大區別是UIView能夠響應用戶事件,而CALayer不能夠。UIView側重於對顯示內容的管理,CALayer側重於對內容的繪製。

你們都知道QuartzCore是IOS中提供圖像繪製的基礎庫。而且CALayer是定義該框架中。難道UIView的底層實現是CALayer??

 

官方作出了明確的解釋:

Displaying Layers in Views

Core Animation doesn't provide a means for actually displaying layers in a window, they must be hosted by a view. When paired with a view, the view must provide event-handling for the underlying layers, while the layers provide display of the content.

The view system in iOS is built directly on top of Core Animation layers. Every instance of UIView automatically creates an instance of a CALayer class and sets it as the value of the view’s layer property. You can add sublayers to the view’s layer as needed.

On Mac OS X you must configure an NSView instance in such a way that it can host a layer.

 

因而可知UIView是基於CALayer的高層封裝。The view system in iOS is built directly on top of Core Animation layers. 

 

UIView 的方法:

layerClass - Implement this method only if you want your view to use a different Core Animation layer for its backing store. For example, if you are using OpenGL ES to do your drawing, you would want to override this method and return the CAEAGLLayer class.

該方法保留了UIView的本質。即對UIView所管理的內容,任何顯示也是受到CALayer的影響的。

 

  1. (3)類似支持

1:類似的樹形結構

2:顯示內容繪製方式

3: 佈局約束


  1. (4) UIView 是什麼,作什麼

UIView是用來顯示內容的,能夠處理用戶事件


  1. (5)CALayer是什麼,作什麼

CALayer是用來繪製內容的,對內容進行動畫處理依賴與UIView來進行顯示,不能處理用戶事件。


  1. (6)爲什麼有兩套結構

並非兩套體系,UIView和CALayer是相互依賴的關係。UIView依賴與calayer提供的內容,CALayer依賴uivew提供的容器來顯示繪製的內容。歸根到底CALayer是這一切的基礎,若是沒有CALayer,UIView自身也不會存在,UIView是一個特殊的CALayer實現,添加了響應事件的能力。

 

  1. (7)二者之間的關係

發之於膚,血之於肉,靈之於魄,男人之於腎的關係。依存的關係

 

結論:

UIView來自CALayer,高於CALayer,是CALayer高層實現與封裝。UIView的全部特性來源於CALayer支持。

相關文章
相關標籤/搜索