對於一切IOS APP來說,我們看的的內容,都是UIView所呈現的。
UIView如場景,UIWindow如舞台,UIView粉墨登場在UIWindow這個舞台上,使我們看到豐富多彩的界面UI。UIWindow本身沒有任何內容,它只提供了一個場所來讓這些UIView來顯示,切換。
通常,一個APP僅有一個UIWindow作為顯示的場所,當我們要進行多屏顯示時,才會使用到多個UIWindow。
1、UIView附著於UIWindow上,只有放在UIWindow上的View,才能被我們看到。
2、UIView本身又可作為容器顯示並管理SubView,使界面更豐富。
3、每個UIView都有一個對應的Core Animation Layer類對象作支持。Layer類對象一般是CALayer類對象。該對象存儲對應UIView對象的一些信息數據,並處理UIView的動畫操作。
有了CALayer對象,主要會提供如下幾點作用:
(1)CALayer對象存儲了對應UIView對象的信息數據,這可以使UIView的渲染次數大大減少,我們可以盡可能的直接讀取CALayer對象裡面的存儲的已經渲染過的數據,而不需要每次都要渲染UIView。
(2)正是因為CALayer對象存儲了UIView的信息,才使得UIView的當前內容可以被操作,進而實現UIView的動畫效果。
(3)我們可以通過直接操作CALayer對象來實現更豐富靈活的顯示及動畫效果。
UIWindow, UIView, Core Animation Layer對象關系如下圖所示:
如前所述,UIView可以添加子View,進而形成superView,subView這樣的父子邏輯關系。
subView被父View放到一個子View隊列裡面進行管理。
最後加入的view會遮擋前面的view。
當App獲取到用戶的操作事件後,會首先將該event傳遞給發生該事件最上層的subview,若該subview不響應該事件,則會傳遞至該view的superview進行響應,這樣一直傳遞下去,直到該事件被響應或由程序丟棄不處理為止。這就是所謂的Event responder chain。
在IOS中,UIView類采取一種按需策略來繪制View的顯示內容。所謂按需策略,就是指僅當你明確告知系統需要對View進行內容重繪時,系統才會調用你的繪制函數重新繪制VIew的內容,否則,系統在大多數情況下僅使用View的內容快照圖片來代替View的內容顯示。
具體實現如下:
1、當一個View第一次顯示在屏幕時,系統會自動調用View的繪制函數,完成內容顯示,同時,為內容保留一份快照圖片。
2、若View的內容不發生改變,則在大多數情況下,系統僅使用快照圖片來表示View內容。這裡注意,系統不會主動詢問是否View的內容發生了改變,需要你主動通知系統內容發生改變從而更新View顯示內容。
3、當你對View的內容做出了改變,調用
setNeedsDisplay
or setNeedsDisplayInRect:
方法通知系統內容發生改變,需要重繪View界面。
4、系統得知內容發生改變後,不會立即重繪View界面,而是當這輪run loop結束,准備重繪內容時,才會對改變內容的View進行重繪。
5、當系統對View進行重繪時,流程並不是統一的。對於自定義的View而言,我們需要重寫
drawRect: 方法。
當然,也可以通過直接改變View對應的Layer對象的方式來改變View的內容。
6、當系統完成對View的重繪後,會采集一張新的內容快照來代表View的內容來用作多數時間的View顯示。
注意,一般的View的幾何形變(如拉伸縮小,不會引起內容重繪,而僅僅是內容快照的拉伸縮小)。
View的內容模式
如前所述,當View顯示在屏幕上後,系統會用一張快照來代替表示內容。
這會照成這麼一種情況,當我們更改View的frame等屬性時,其內容(內容快照),並不一定會同時改變。對於內容顯示的方式,取決於UIView對象的Content Modes.默認的系統會采取UIViewContentModeScaleToFill模式,使內容快照拉伸填充滿整個View區域。Content Mode的幾個形式如下圖:
注意,當設置了View的ContentMode後,每一次View的幾何形變都會引起系統調用View的drawRect:方法來重繪View,因此應當避免使用該屬性,同時對於系統View,我們絕不應該用屬性。
IOS系統的坐標系統如下所示:
UIWindow, UIView都有自己的坐標系統。對於UIView常用的屬性Frame,Bound,Center其屬性是相對於不同坐標系統的。具體如下:
A view object tracks its size and location using its frame
, bounds
, and center
properties:
The frame
property contains the frame rectangle, which specifies the size and location of the view in its superview’s coordinate system.
The bounds
property contains the bounds rectangle, which specifies the size of the view (and its content origin) in the view’s own local coordinate system.
The center
property contains the known center point of the view in the superview’s coordinate system.
When you set the frame
property, the size value in the bounds
property changes to match the new size of the frame rectangle. The value in the center
property similarly changes to match the new center point of the frame rectangle.
When you set the center
property, the origin value in the frame
changes accordingly.
When you set the size of the bounds
property, the size value in the frame
property changes to match the new size of the bounds rectangle.
setNeedsLayout
方法,讓系統重新布局(即讓系統在下一輪更新過程中,主動調用我們重寫的layoutSubviews
)調用 setNeedsDisplay
or setNeedsDisplayInRect:
方法,讓系統對View內容進行重繪。(即讓系統在下一輪內容更新過程中,主動調用我們重寫的drawRect:
)函數。更改UIView的屬性,或通知某個controller對象。