View編程指南(一)


一、View和Window簡介

在iOS中,我們用window和view來呈現(xiàn)應用的內(nèi)容。事實上window本身不能呈現(xiàn)任何可視的內(nèi)容,但是它可以為view提供基本的容器功能。view相當于定義了window中的一塊用于顯示內(nèi)容的區(qū)域。例如:用來顯示圖片、文字、圖形或者以上幾者的組合的view。你也可以用view來組織和管理其他view。

每個應用都至少有一個window和一個view組成。UIKit和其他系統(tǒng)框架提供了一些預定義的view:從最簡單的button、text label到復雜的table view、picker view、scroll view。當預定義的view不能滿足你的需求的時候,你還能創(chuàng)建自定義view來管理view的繪制和事件處理。

view是UIView類(或其子類)的實例,它管理應用的window中的一塊矩形區(qū)域。view負責繪制內(nèi)容、處理事件、管理subview的布局。繪制內(nèi)容涉及到使用Core Graphics、OpenGL ES或者UIKit來繪制形狀、圖片和文字。view同時還負責處理對其矩形區(qū)域內(nèi)發(fā)生的觸摸或者手勢事件。在view的層級結(jié)構(gòu)(hierarchy)中,parent view負責他們的child view的布局并且可以動態(tài)的隨時調(diào)整布局,這在界面旋轉(zhuǎn)或者實現(xiàn)界面動畫的情況下尤其有用。

window是UIWindow類的實例并且用于處理應用總的界面呈現(xiàn)。一般來說應用的window基本不會變化:當一個window被創(chuàng)建后,它就待在那兒,只有window里的view會經(jīng)常發(fā)生變化?;旧弦粋€應用就一個window,如果設備接入了外部顯示,那么應用會創(chuàng)建第二個window用于在外部顯示上呈現(xiàn)內(nèi)容。

動畫用來為用戶提供內(nèi)容變化的視覺反饋。系統(tǒng)定義了在模態(tài)化view和不同view之間切換的標準動畫。當然view的很多屬性也可以使用動畫效果,例如:view的透明度、位置、背景色等。如果你直接使用view底層的Core Animation Layer,你還能做出更多炫酷的動畫效果。

Interface Builder是一個可視化編輯window和view的工具。使用IB,你的view都存放在一個nib(xib)文件中。你可以把nib文件想像成是存儲view和其他對象的序列化資源文件。當你在運行時load一個nib文件的時候,里面的對象會重新組成到內(nèi)存中并且可以被代碼操作。

二、View和Window的結(jié)構(gòu)

1. View結(jié)構(gòu)基礎


view和Core Animation Layer配合來處理view的繪制和動畫效果。每個view的背后都有一個layer對象(通常是CALayer類的實例)負責這個view的繪制和動畫效果。大多數(shù)情況下你只需要和UIView的接口打交道,只有在某些特定的情況下你才需要操作layer對象。

為了幫助理解view和layer之間的關系,可以參考圖1-1。在圖1-1中我們可以看到UIBarButtonItem是沒有l(wèi)ayer的,因為它是由UIToolbar繪制出來的,并非一個獨立的view。

圖1-1

2. View的層級結(jié)構(gòu)和Subview管理


當一個view包含另一個view的時候,兩個view之間就有了parent-child關系。child view就叫subview,parent view就叫superview。

視覺上,subview的內(nèi)容遮蓋superview全部或部分的內(nèi)容空間。如果subview是不透明的,那他就徹底遮蓋了superview對應的部分。如果subview是部分透明的,那這兩個view的內(nèi)容就會混合在一起顯示(想象成高斯模糊的那種效果)。每個superview將它的subview存儲在一個排序過的數(shù)組里。越晚添加的或者順序越大的顯示在越上面。

superview - subview的這種關系也會影響到一些view的行為。例如:改變superview的大小也會使subview的大小和位置發(fā)生改變。還包括改變superview的透明度、改變superview的坐標系統(tǒng)。

view的層級關系還影響到事件的傳遞。當某個view中發(fā)生了觸摸事件,如果當前的這個view無法處理,事件會順著view的層級向上傳遞。特定的view還會把事件傳遞給responder對象,例如一個view controller。如果事件最終傳遞到最頂級的application對象,通常這個事件就被丟棄了。

3. View的繪制周期


UIView使用按需繪制的模式來呈現(xiàn)內(nèi)容。當一個view首次呈現(xiàn)在屏幕上時,系統(tǒng)會要求它繪制一下它的內(nèi)容。然后系統(tǒng)會捕捉一張快照,并且一直使用它。如果你不改變view的內(nèi)容,那么view的繪制代碼就不會被再次執(zhí)行。當你改變了view的顯示內(nèi)容,你應該使用view的setNeedsDisplay或setNeedsDisplayInRect方法來要求重繪。如果你是自定義UIView的子類,那么通常你應該重載drawRect方法來繪制你的view。你也有其他方法來繪制view,例如直接在layer上繪制,但通常你應該重載drawRect來實現(xiàn)自定義view的繪制。

4. View的Content Mode


每個view有一個content mode,當view的幾何形狀發(fā)生變化時,它用來控制view的內(nèi)容是否需要重繪或者將如何改變。

當你進行如下操作時,content mode將會起作用:

  • 改變view的frame或者bounds的寬高
  • view的transform屬性含有scale factor

默認的content mode是UIViewContentModeScaleToFill。它會使view的內(nèi)容縮放以適應新的frame尺寸。圖1-2顯示了各種content mode下的內(nèi)容縮放情況。

圖1-2

content mode有助于避免不必要的內(nèi)容重繪,當然你也可以設置content mode為UIViewContentModeRedraw來強制view在每次縮放或尺寸改變時重繪(調(diào)用drawRect方法),但是通常你應當避免這么做。

5. 可拉伸的View


你可以指定view的某塊區(qū)域為可拉伸,這樣當view的尺寸改變的時候,只有可拉伸的區(qū)域會受到影響。一般會在按鈕上使用這種技術(shù)。圖1-3顯示了可拉伸時,view是如何變化的。

圖1-3

使用view的content stretch屬性來指定可拉伸的區(qū)域。這個屬性接受一個rectangle值來表示可拉伸區(qū)域,并且這個值會歸一化到0.0 - 1.0。這樣當拉伸發(fā)生時,系統(tǒng)可以用view的當前bounds以及scale factor乘以這個歸一化的值來決定如何縮放。另外view的content mode也會影響拉伸。只有UIViewContentModeScaleToFill、UIVieweContentModeScaleAspectFit和UIViewContentModeScaleAspectFill這幾個content mode才會出發(fā)拉伸。

推薦在設置view的背景時使用一個可拉伸的UIImage對象來實現(xiàn)拉伸

6. 內(nèi)置動畫支持


UIView類的一些屬性是支持半自動動畫的。你只需要:

  1. 告訴UIKit你要使用動畫了!
  2. 改變這些屬性的值

這些屬性有:

  • frame —— 位置和尺寸的動畫
  • bounds —— 尺寸動畫
  • center —— 位置動畫
  • transform —— 旋轉(zhuǎn)和縮放動畫
  • alpha —— 改變透明度
  • backgroundColor —— 改變背景色
  • cententStretch —— 改變view如何拉伸

一般來說,viewcontroller之間過度時會使用動畫。當然你也可以直接在兩個view之間使用動畫。另外,除了使用UIKit類來實現(xiàn)動畫,你還能使用Core Animation Layer來實現(xiàn)動畫,它能提供更多的時間和屬性上的控制。


下篇 View編程指南(二)

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

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