View Programming Guide For IOS 翻譯

View Programming Guide For IOS 官方地址


View and Window Architecture(視圖與窗口的結構)


View Architecture Fundamentals(視圖的基礎結構)


當你處理視圖相關的問題時,最常接觸到的類是UIView. View 對象在屏幕上定義了一塊矩形區域.并且管理這塊區域的點擊事件. View 也可以作為其他 View 的父視圖.并且管理對應子 View 位置和大小. UIView 類做了大量的管理各個視圖的關系,你也可以自定義這些關系.

視圖與 Core Animation 的 layer 結合在一起,用于管理視圖動畫內容相關.每個UIKIt中的視圖下層都有 layer 對象 .管理下層儲存和管理視圖動畫相關.大多數情況下,你執行相關的效果只需要使用 UIView 的公開屬性就可以了.然后,如果你想得到更多的控制視圖動畫相關的能力,你可以使用視圖的layer層.

為了更好的理解視圖與layer相關,我們通過下面的例子來理解.

Core Animation 的 layer 對象的功能對底層的實現有影響.實際上繪制視圖的代碼盡可能少去調用.當代碼被調用,繪制結果將被 Core Animation 緩存下來,并且盡可能的重用.重用已經繪制好的視圖可以減少重新繪制視圖所造成的額外消耗.重用機制在動畫執行時有重要作用.

View Hierarchies and Subview Management


父視圖通過數組來保存子視圖,子視圖在數組中的順序是會影響視圖的顯示的
父視圖中有兩個子視圖,這兩個子視圖有重疊部分,那么后添加(或者是被移動到數組最后)的視圖將會顯示在上面.
父視圖子視圖的關系也會影響視圖行為,改變父視圖的大小將會導致子視圖的位置跟大小發生改變.其他改變也會影響子視圖,比如:

1、隱藏父視圖 
2、改變父視圖的透明度
3、改變父視圖的坐標系統

視圖的排布決定了程序如何響應點擊事件.
當一個點擊事件發生在屏幕上時,系統將發送事件到對應的視圖上,對應視圖來處理事件.如果對應的視圖沒有處理事件的能力,那么事件將傳給對應視圖的父視圖.如果父視圖也不能處理,那么事件將傳給父視圖的父視圖.以此類推.
這是一個響應者鏈 Response Chain .
視圖也可以將事件傳給交互的實體,比如viewController.
如果沒有實體處理事件,事件最終將傳給應用實體 (Application Object).它來統一丟棄(discard)

The View Drawing Cycle


UIView類是以 “按需繪圖模式" 去展現內容.
當一個視圖第一次展現在屏幕上時,系統會要求它去繪制自己的內容.
系統將獲取View中內容的 snapshot(截屏)并用截屏 snapshot(截屏)作為視圖的可視部分的代替.
如果你從未改變視圖內容,那么視圖繪制代碼將不會被執行.
對應的 snapshot(截屏)會被重復利用.在大多數跟這個視圖相關的操作中.如果你改變了視圖的內容,你去通知系統對應的視圖發生了改變.視圖將重復繪制視圖的過程并且獲取視圖新的截屏.

當視圖的內容發生改變,你不需要直接去重新繪制視圖.
你通過使setNeedsDisplaysetNeedsDisplayInRect:方法主動去作廢之前的視圖.
這些方法告訴系統視圖的內容被修改了,在下個opportunity需要重新繪制.
系統將會在下次初始化繪制動作前和現在的runloop結束后重新繪制.
這個等待將會給你充分的時間去(invalidate)作廢多個View,或者是從View層級中移除視圖,隱藏視圖,改變視圖大小,改變視圖位置.
所有你做的改變將會同時反應出來.

到了繪制 view 的內容的時機,真正決定繪制內容是取決于 view 和 view 的屬性.
系統視圖實現了私有的繪制方法,并在頭部展示出來.
一些系統的視圖類將接口暴露出來,你通過修改相關屬性來控制視圖的顯示.
自定一個視圖UIView子類,你可以通過重寫子類中drawRect:方法,去繪制視圖.還有其他方式來提供視圖內容,比如直接設置內容的(underlying layer)下層.但是drawRect:方式是最通用實現方法.

Content Modes


每個view都有 content mode, content mode 的作用是在視圖的坐標發生改變時,如果去回收利用內容。當一個view第一次被展示時,它的內容將會被捕獲,捕獲的結果以bitmap的形式.改變坐標系時,bitmap將不會被重新繪制. content mode 屬性決定bitmap該如何被拉伸。或者僅僅只是移動位置。

視圖的 Content Mode 將被應用在下面的情況

  • 當你改變 frame 或者 bounds 的高和寬時,將會應用 contentmode.
  • 當修改 View 的 transform 屬性時,transform 屬性包含放大所有的因素時。

大多數view的 contentmode 是 UIViewContentModeScaleToFill

請自行查找 contentmode 各個值

StretchableViews(可拉伸區域)


你可以定義一塊區域作為可拉伸的區域,當view的大小改變時,只有在可拉伸區域的內容受到影響.

經常人們會定義一個可拉伸區域,作為試圖的一個重復的模塊

可拉伸區域可以從xy軸兩個方向拉伸

通過contentStretch屬性來申明一個可拉伸的區域,值的范圍是0~1

contentmodel在可拉伸區中如何拉伸中起到很重要的作用.可拉伸區域只有在contentmode導致視圖內容被放大或者縮小時.

這意味著只有在contentmode為以下內容時才可以被拉伸:

  • UIViewContentModeScaleToFill,
  • UIViewContentModeScaleAspectFit,
  • UIViewContentModeScaleAspectFill

Built-In Animation Support


在每一個視圖(View)下面都有一個 layer (圖層)的好處是,我們可以很容易完成跟view相關的動畫.
想要執行一個動畫,你必須要做一下兩個步驟.

  1. 告訴UIKIt,將要執行一個動畫
  2. 改變屬性的值

改變以下UIView屬性時,將會有動畫

  • frame — Use this to animate position and size changes for the view.

  • bounds — Use this to animate changes to the size of the view.

  • center — Use this to animate the position of the view.

  • transform — Use this to rotate or scale the view.

  • alpha — Use this to change the transparency of the view.

  • background Color — Use this to change the background color of the view.

  • content Stretch — Use this to change how the view’s contents stretch.

Core Animation 將會告訴你如何開發動畫

視圖的幾何意義上的坐標系

在UIkit中以左上角為坐標原點,使用 floating point number

每一個view和屏幕都有自己的坐標系。

The Relationship of the Frame,Bounds,and Center Properties

視圖

默認情況下,子視圖超出父視圖時,父視圖將不會裁剪子視圖.你可以設置clipsToBounds,來改變這個效果.
不管子視圖有沒有超區父視圖,當事件傳過來時,只會在父視圖的frame中響應。

Points Versus Pixels 點與像素之間的關系

Points(點)提供一個frame(矩形區域)用來繪圖。
ios是一個以點為計量單位來定義了用戶坐標空間的系統
一個點并不是代表一個在屏幕上的像素

The Runtime Interaction Model for Views 運行時交互

當用戶點擊你的交互界面,或者你代碼修改一些object,一系列復雜的事件將要被觸發在UIKit中,來管理交互.這些事件是有序列的。在UIKit調用這個特定序列的事件中特殊時期,UIKit將會調用你的類,來讓你的類處理對應的交互事件。
下面是這個事件隊列。

sequence of event
sequence of event
  1. 用戶點擊屏幕

  2. 硬件報告事件給UIKit

  3. UIKit打包touch事件到UIEvent事件,并將對應事件發送到對應的視圖。

  4. 視圖的事件處理代碼將被觸發來回應對應的事件。

    • 改變視圖的屬性
    • 調用setNeedsLayout方法 標記view需要 layout
    • 調用setNeedsDisplay: 或者 setNeedsDisplayInRect:去標記視圖需要重新繪制
    • 通知視圖控制器去改變部分數據
  5. 如果視圖的幾何坐標修改了,UIKit需要根據下面的規則更新它的子視圖。

    • 如果你設置 autoresizing,那么UIKit將會根據你的設置來調整視圖。
    • 如果你的視圖實現了layoutSubviews 方法,UIKit將會調用它。
      • 你可以重寫此方法來自定義視圖。使用本方法來調整子視圖位置和大小。舉個例子,視圖提供一個大的滑動區域。
  6. 如果任何一個視圖被標記為重新繪制,UIKit將會要求視圖去重寫繪制

  7. 任何更新完之后的視圖將被復合成對應區域的內容,發給繪圖硬件繪制。

  8. 繪圖硬件將繪制完好的內容展現到屏幕上。

總結一下如何自定義一個視圖

  1. 事件響應方法

    • -touchesBegan:withEvent:
    • -touchesMoved:withEvent:
    • -touchesEnded:withEvent:
    • -touchesCancelled:withEvent:
  2. layoutSubviews

  3. drawRect

上面的方法是我們通常自定義一個視圖需要重寫的方法。但你不必要每個方法都去實現。如果你想要用手勢來處理事件,你不需要去重寫上面的所有方法。通常,如果你的視圖沒有包含子視圖或者他自己的大小沒有改變,那么就沒有重寫layoutSubview的必要了。最后,當你需要在運行時來修改視圖的和你正在使用 UIKit 和 Core Graphics 去繪圖時 你可以重寫 drawRect 方法是、

window

一個應用程序至少有一個window
window的作用
1.包含可視部分
2.發送事件給你的視圖和其他object
3.跟viewcontroller一起工作,加速旋轉屏幕的效果

跟Window相關的任務

大多數程序,只有在初始化window時才與window發生交互.然后你可以使用程序窗口來執行一些跟程序相關的任務.

  1. 使用window將點和矩形的塊轉換到以window坐標系的坐標系統
  2. 使用窗口通知去響應窗口相關改變.

Creating and Configuring a Window(創建和配置window)

我們可以通過 Interface Builder 或者代碼去創建Window.不管使用哪種方法,我們需要在啟動的時候創建Window.并且我們需要retain window. store a reference 在我們應用程序的代理中UIApplicationDelegate實例. 如果你的程序創建了一個新的Window,使用懶加載(需要的時候再加載).
你必須在創建程序的主window,在程序啟動的時候.不管是在前臺foreground,還是后臺background.當你的程序在后臺啟動的時候,你需要保證你的window不被顯示,直到你的應用程序到前臺工作.

Creating window in Interface Builder

xcode項目自動為你做好創建主屏幕的工作.每個項目中都包涵一個Main.storyBoard.除此之外,模板還創建一個outlet,對應程序的主屏幕.你通過outlet去獲取主屏幕.

通過Interface builder創建主屏幕是,要在launch option打開 Full Screen.如果你不這樣做,你的主屏幕可能比設備的屏幕小,用戶動作可能不能被你的視圖處理.因為主屏幕接收不到屏幕意外的touch 事件.因為view默認不會被主屏幕裁剪.View可以展現在屏幕上,但是有可能不處理touch事件.將launch option 中對應key 設置為全屏.使得window能適應整個屏幕.

如果你想更新使用Interface builder來創建主屏幕.現在Interface builder拖進一個屏幕window object到你的nib文件中.你還需要做到以下幾步.

  1. 想要在運行時獲取當前屏幕,你需要將window跟一個outlet關聯起來.通常做法是在 應用代理中或者 nib 文件對應的 File owner.
  2. 如果你想要升級,你需要將程序的主nib文件設置為當前的文件.你還必須在 plist中設置 NSMainNibKey的值為你的nib文件名.改變這個值時,你需要確認 nib文件已經被加載并且能被獲取到.

Creating a Window Programmatically 代碼創建屏幕


代碼創建主屏幕,你應該在程序代理的application:didFinishLaunchingWithOptions:方法中創建下面的代碼
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

Displaying Content on an External Display

想要顯示外置的內容,你需要給你的應用添加額外的window.通過screen object去獲取,并展示額外的內容.
通常新的window可以被main Screen獲取到.改變windowscreen object致使你屏幕的內容發生響應的改變.只要window可以被當前screen獲取到,你就可以像在主屏幕中添加view并展示一樣做相同的操作.
UIScreen類擁有一個screen object的列表.代表著可以獲取的物理顯示.通常,只有一個screen object作為ios應用程序的主顯示,但是設備是支持額外顯示功能的.所有可以擁有其他的screen.有retina display顯示功能的才有額外顯示功能.3gs就沒有這個功能.

  1. 在應用程序構建時,注冊screen 連接和斷開通知

  2. 當需要顯示的時候,創建并配置一個window

    • 通過UIScreen的screen屬性去持有一個screen object,做一些展示額外顯示的準備.
    • 創建一個UIWindow實體并配置響應的大小位置.
    • 設置UIScreen object為Window的screen屬性.
    • 適配screen object,為了支持你所以要顯示的內容.
    • 添加合適的view到UIWindow上.
  3. 顯示這個window

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

推薦閱讀更多精彩內容