翻譯:iOS視圖控制器編程指南(四)——定義子類(Defining Your Subclass)

當(dāng)你使用UIViewController的自定義子類來展示你應(yīng)用內(nèi)容秕脓。大多數(shù)自定義視圖控制器是內(nèi)容視圖控制器队魏,他們有自己的視圖并負(fù)責(zé)管理這些視圖中的數(shù)據(jù)室囊。相比之下泼橘,容器視圖控制器并不擁有所有的視圖饲宿,一些視圖是由其他視圖控制器管理厦酬。大多數(shù)定義內(nèi)容和容器視圖控制器的步驟是一樣的,這些將在下面幾節(jié)中討論瘫想。

內(nèi)容視圖控制器仗阅,最常見的父類如下:

·使用UITableViewController,尤其是當(dāng)你的視圖控制器的主要視圖是表国夜。

·使用UICollectionViewController减噪,尤其是當(dāng)你的視圖控制器的主要視圖是一個集合視圖。

·其他所有的視圖控制器使用UIViewController车吹。

對于容器視圖控制器筹裕,父類取決于是否修改一個已經(jīng)存在的容器類或者創(chuàng)建你自己的。對于現(xiàn)有容器礼搁,選擇你想要修改的視圖控制器類饶碘。對于新的容器視圖控制器,通常繼承UIViewController馒吴。關(guān)于創(chuàng)建容器視圖控制器的更多信息扎运,參見實(shí)現(xiàn)容器視圖控制器(Implementing a Container View Controller)。

定義UI

為視圖控制器定義UI通常使用Xcode中的storyboard饮戳。雖然也可以通過編程創(chuàng)建UI豪治,但storyboard是一個非常好的方法來可視化視圖控制器的內(nèi)容并在不同的環(huán)境(如果需要)定制你的視圖層級。構(gòu)建視覺UI可以讓你快速的改變并讓你看到結(jié)果扯罐,而無需構(gòu)建和運(yùn)行應(yīng)用负拟。

圖4-1展示了storyboard的例子。每個矩形區(qū)域代表一個視圖控制器和其相關(guān)的視圖歹河。視圖控制器之間的箭頭是視圖間關(guān)系和聯(lián)線掩浙。Relationships連接一個容器視圖控制到它的子視圖控制器。Segues讓你在界面視圖控制器之間導(dǎo)航秸歧。

圖4-1包含一組視圖控制器和視圖的storyboard

每個新項(xiàng)目都有一個主storyboard厨姚,通常包含一個或多個視圖控制器。通過拖放它們到畫布上键菱,可以添加新的視圖控制器到storyboard谬墙。新視圖控制器最初沒有相關(guān)的類成肘,你必須使用標(biāo)示符賦值蠢琳。

使用storyboard編輯器來完成以下操作:

·為一個視圖控制器添加昌简、整理并配置視圖沦疾。

·連接outlet和action,參見處理用戶交互(Handling User Interactions)造虎。

·創(chuàng)建視圖控制器之間的關(guān)系和聯(lián)線傅蹂,參見使用segues(Using Segues)。

·為不同的size類定義布局和視圖累奈,參見構(gòu)建自適應(yīng)界面(Building an Adaptive Interface)贬派。

·添加手勢識別器來處理用戶交互視圖,參見iOS事件處理指南(Event Handling Guide for iOS)澎媒。如果你是使用storyboard來建立你的界面搞乏,你可以在iOS應(yīng)用開發(fā)中找到循序漸進(jìn)的指示來創(chuàng)建基于storyboard的界面。

處理用戶交互

應(yīng)用的響應(yīng)者對象處理傳入的事件并采取適當(dāng)?shù)膭幼鹘渑km然視圖控制器是響應(yīng)者對象请敦,但他們很少直接處理觸摸事件。相反储玫,視圖控制器通常以以下方式處理事件侍筛。

·視圖控制器為處理高級別事件定義動作方法。動作方法響應(yīng):

1.指定動作撒穷∠灰控制器和一些視圖調(diào)用一個動作方法來響應(yīng)特定交互。

2.手勢識別器端礼。手勢識別器調(diào)用一個動作方法來響應(yīng)當(dāng)前手勢狀態(tài)禽笑。使用視圖控制器來處理狀態(tài)變化或響應(yīng)完成的手勢。

·視圖控制器觀察系統(tǒng)或其他對象發(fā)送的通知蛤奥。通知報告變化佳镜,同時也是視圖控制器更新狀態(tài)的一種方式。

·視圖控制器作為其他對象的數(shù)據(jù)源或代理凡桥。視圖控制器通常用于管理表的數(shù)據(jù)蟀伸、集合視圖的數(shù)據(jù)。你可以使用它們作為對象的代理缅刽,例如CLLocationManager對象啊掏,發(fā)送更新的位置值到它的代理。

響應(yīng)事件通常包括更新視圖的內(nèi)容衰猛,這需要有這些視圖的引用脖律。視圖控制器可以定義任何視圖的outlet。使用列表4-1中的語法來聲明你的outlet屬性腕侄。列表中的自定義類定義了兩個outlet(IBOutlet指定的關(guān)鍵字)和一個動作方法(IBOutlet指定的返回類型)。雖然動作方法響應(yīng)按鈕點(diǎn)擊事件,Outlet存儲了storyboard中按鈕和文本框中的引用冕杠。

列表4-1在視圖控制器類中定義outlet和動作微姊。

OBJECTIVE-C
<pre><code>
@interface

MyViewController:UIViewController

@property(weak,nonatomic)IBOutletUIButton*myButton;

@property(weak,nonatomic)IBOutletUITextField*myTextField;

-(IBAction)myButtonAction:(id)sender;

@end
</pre></code>

SWIFT
<pre><code>
classMyViewController:UIViewController{

@IBOutletweakvarmyButton:UIButton!

@IBOutletweakvarmyTextField:UITextField!

@IBActionfuncmyButtonAction(sender:id)

}
</pre></code>
在storyboard中,記得連接視圖控制器的outlet和動作到相應(yīng)的視圖分预。連接storyboard中的outlet和動作確保黨視圖加載時他們已配置好兢交。更多關(guān)于如何在IB中創(chuàng)建outlet和動作連接的方法,參見IB連接幫助(Interface Builder Connections Help)笼痹。更多關(guān)于如何處理應(yīng)用中事件配喳,參見iOS事件處理指南(Event Handling Guide for iOS)。

在運(yùn)行時顯示視圖

Storyboard使加載和顯示視圖控制器的視圖變得簡單凳干。UIKit自動從storyboard加載視圖晴裹。隨著加載過程,UIKit執(zhí)行以下的任務(wù)序列:

1.使用storyboard文件中的信息實(shí)例化視圖救赐。

2.連接所有outlet和動作涧团。

3.指定根視圖為視圖控制器的視圖屬性。

4.調(diào)用視圖控制器的awakeFromNib方法经磅。

當(dāng)調(diào)用此方法泌绣,視圖控制器的特征集合為空,視圖可能不在最后的位置预厌。

5.調(diào)用視圖控制器的viewDidLoad方法阿迈。

使用該方法添加或刪除視圖,修改布局約束轧叽,加載視圖數(shù)據(jù)苗沧。

在屏幕上顯示視圖控制器的視圖前,UIKit提供額外的機(jī)會準(zhǔn)備這些視圖犹芹,之后顯示在屏幕上崎页。具體說來,UIKit執(zhí)行以下任務(wù)序列:

1.調(diào)用視圖控制器的viewWillAppear:方法讓它知道視圖將出現(xiàn)在屏幕上腰埂。

2.更新視圖布局飒焦。

3.在屏幕上顯示視圖。

4.當(dāng)視圖在屏幕上調(diào)用viewDidAppear:方法屿笼。

當(dāng)添加牺荠、刪除或修改視圖的大小或位置,記得添加和刪除用于這些視圖的約束驴一。修改視圖層級的布局相關(guān)變更會導(dǎo)致UIKit布局混亂休雌。在接下來的更新周期,布局引擎計算視圖的大小和位置肝断,使用當(dāng)前布局約束并將這些更改應(yīng)用到視圖層級結(jié)構(gòu)杈曲。

關(guān)于如何創(chuàng)建視圖而不使用storyboard的更多信息驰凛,參見UIViewController類引用(UIViewController Class Reference)中的視圖管理信息。

管理視圖布局

當(dāng)視圖的大小和位置發(fā)生變化担扑,UIKit更新視圖層級的布局信息恰响。對于使用自動布局的視圖,UIKit使用自動布局引擎并根據(jù)當(dāng)前約束使用它更新布局涌献。UIKit還允許其他對象胚宦,例如活動展示控制器,知道布局變化燕垃,這樣它們可以做相應(yīng)的回應(yīng)枢劝。

在布局過程中,在幾個點(diǎn)上UIKit發(fā)出通知卜壕,這樣可以執(zhí)行額外的布局相關(guān)任務(wù)您旁。使用這些通知來修改布局約束或者在布局約束應(yīng)用后做最后的布局調(diào)整。在布局過程中印叁,UIKit為每個受影響的視圖控制器做如下任務(wù):

1.根據(jù)需要被冒,更新視圖控制器和視圖的特征集合,參見特征和大小變更的時間(When Do Trait and Size Changes Happen)

2.調(diào)用視圖控制器的viewWillLayoutSubviews方法轮蜕。

3.調(diào)用當(dāng)前UIPresentationController對象的containerViewWillLayoutSubviews方法昨悼。

4.調(diào)用視圖控制器的根視圖的layoutSubviews方法。

該方法默認(rèn)使用可用約束實(shí)現(xiàn)計算新布局信息跃洛。該方法遍歷視圖層級并為每個子視圖調(diào)用layoutSubviews率触。

5.運(yùn)用計算好的布局信息到視圖。

6.調(diào)用視圖控制器的viewDidLayoutSubviews方法汇竭。

7.調(diào)用當(dāng)前UIPresentationController對象的containerViewDidLayoutSubviews方法葱蝗。

視圖控制器可以使用viewWillLayoutSubviews和viewDidLayoutSubviews方法執(zhí)行額外更新,這些更新可能會影響布局過程细燎。布局之前两曼,你可以添加或刪除視圖,更新視圖的大小和位置玻驻,更新約束悼凑,或者更新其他視圖相關(guān)屬性。布局之后璧瞬,可能重新加載表數(shù)據(jù)户辫,更新其他視圖的內(nèi)容,或者最后調(diào)整視圖大小和位置嗤锉。

這里有些小提示可以有效的管理布局:

·使用自動布局渔欢。使用自動布局創(chuàng)建的約束是一種靈活和簡單的方式在不同屏幕尺寸上定位你的內(nèi)容。

·利用頂部和底部布局參考線瘟忱。內(nèi)容布局中的參考線確保內(nèi)容總是可見的奥额。頂部位置的布局參考線把狀態(tài)欄和導(dǎo)航欄的高度考慮在內(nèi)苫幢。同樣的,底部位置的布局參考線把tab欄或工具欄的高度考慮在內(nèi)披坏。

·當(dāng)添加或刪除視圖時記得更新約束态坦。如果動態(tài)添加或刪除視圖,記得更新相應(yīng)的約束棒拂。

·當(dāng)視圖控制器的視圖在動畫時,暫時刪除約束玫氢。當(dāng)使用UIKit核心動畫完成視圖動畫帚屉,在動畫期間刪除約束并在動畫完成時添加約束。如果在動畫期間視圖的位置或尺寸改變漾峡,記得更新約束攻旦。

關(guān)于顯示控制器和視圖控制器結(jié)構(gòu)中的作用信息,參見present和transit過程(The Presentation and Transition Process)生逸。

有效管理內(nèi)存

盡管大多數(shù)方面的內(nèi)存分配由你來決定牢屋,表4-1列出了的UIViewControll方法,這些方法最有可能出現(xiàn)分配或釋放內(nèi)存槽袄。大多數(shù)回收涉及刪除對象的強(qiáng)引用烙无。刪除對象的強(qiáng)引用,設(shè)置指向改對象的屬性和變量為nil遍尺。

任務(wù) 方法 討論
分配視圖控制器所需的關(guān)鍵數(shù)據(jù)結(jié)構(gòu) Initialization methods 自定義initialization方法(無論是否名為init或其他)總是負(fù)責(zé)把視圖控制器對象放到一個已知狀態(tài)截酷。使用這些方法來分配任何數(shù)據(jù)結(jié)構(gòu)以確保正確的操作。
分配或加載視圖中顯示的數(shù)據(jù) viewDidLoad 使用viewDidLoad方法加載要顯示的任何數(shù)據(jù)對象乾戏。調(diào)用此方法時迂苛,保證視圖對象存在并且處于已知狀態(tài)。
響應(yīng)低內(nèi)存通知 didReceiveMemoryWarning 使用該方法釋放視圖控制器所有相關(guān)對象鼓择。盡量釋放內(nèi)存三幻。
釋放視圖控制器的關(guān)鍵數(shù)據(jù)結(jié)構(gòu) dealloc 覆蓋該方法在最后清理視圖控制器類。系統(tǒng)自動釋放實(shí)例變量對象及類屬性呐能,所以你不需要顯示的釋放它們念搬。

表4-1進(jìn)行分配和釋放內(nèi)存的地方

官方原文地址:

https://developer.apple.com/library/prerelease/ios/featuredarticles/ViewControllerPGforiPhoneOS/DefiningYourSubclass.html#//apple_ref/doc/uid/TP40007457-CH7-SW1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市催跪,隨后出現(xiàn)的幾起案子锁蠕,更是在濱河造成了極大的恐慌,老刑警劉巖懊蒸,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣倾,死亡現(xiàn)場離奇詭異,居然都是意外死亡骑丸,警方通過查閱死者的電腦和手機(jī)舌仍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門妒貌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人铸豁,你說我怎么就攤上這事灌曙。” “怎么了节芥?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵在刺,是天一觀的道長。 經(jīng)常有香客問我头镊,道長蚣驼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任相艇,我火速辦了婚禮颖杏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坛芽。我一直安慰自己留储,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布咙轩。 她就那樣靜靜地躺著获讳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪臭墨。 梳的紋絲不亂的頭發(fā)上赔嚎,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音胧弛,去河邊找鬼尤误。 笑死,一個胖子當(dāng)著我的面吹牛结缚,可吹牛的內(nèi)容都是我干的损晤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼红竭,長吁一口氣:“原來是場噩夢啊……” “哼尤勋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茵宪,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤最冰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后稀火,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暖哨,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年凰狞,在試婚紗的時候發(fā)現(xiàn)自己被綠了篇裁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沛慢。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖达布,靈堂內(nèi)的尸體忽然破棺而出团甲,到底是詐尸還是另有隱情,我是刑警寧澤黍聂,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布躺苦,位于F島的核電站,受9級特大地震影響产还,放射性物質(zhì)發(fā)生泄漏圾另。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一雕沉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧去件,春花似錦坡椒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宫莱,卻和暖如春丈攒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背授霸。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工巡验, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碘耳。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓显设,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辛辨。 傳聞我的和親對象是個殘疾皇子捕捂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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