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

當你使用UIViewController的自定義子類來展示你應用內容。大多數自定義視圖控制器是內容視圖控制器,他們有自己的視圖并負責管理這些視圖中的數據。相比之下,容器視圖控制器并不擁有所有的視圖,一些視圖是由其他視圖控制器管理。大多數定義內容和容器視圖控制器的步驟是一樣的,這些將在下面幾節中討論。

內容視圖控制器,最常見的父類如下:

·使用UITableViewController,尤其是當你的視圖控制器的主要視圖是表。

·使用UICollectionViewController,尤其是當你的視圖控制器的主要視圖是一個集合視圖。

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

對于容器視圖控制器,父類取決于是否修改一個已經存在的容器類或者創建你自己的。對于現有容器,選擇你想要修改的視圖控制器類。對于新的容器視圖控制器,通常繼承UIViewController。關于創建容器視圖控制器的更多信息,參見實現容器視圖控制器(Implementing a Container View Controller)。

定義UI

為視圖控制器定義UI通常使用Xcode中的storyboard。雖然也可以通過編程創建UI,但storyboard是一個非常好的方法來可視化視圖控制器的內容并在不同的環境(如果需要)定制你的視圖層級。構建視覺UI可以讓你快速的改變并讓你看到結果,而無需構建和運行應用。

圖4-1展示了storyboard的例子。每個矩形區域代表一個視圖控制器和其相關的視圖。視圖控制器之間的箭頭是視圖間關系和聯線。Relationships連接一個容器視圖控制到它的子視圖控制器。Segues讓你在界面視圖控制器之間導航。

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

每個新項目都有一個主storyboard,通常包含一個或多個視圖控制器。通過拖放它們到畫布上,可以添加新的視圖控制器到storyboard。新視圖控制器最初沒有相關的類,你必須使用標示符賦值。

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

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

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

·創建視圖控制器之間的關系和聯線,參見使用segues(Using Segues)。

·為不同的size類定義布局和視圖,參見構建自適應界面(Building an Adaptive Interface)。

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

處理用戶交互

應用的響應者對象處理傳入的事件并采取適當的動作。雖然視圖控制器是響應者對象,但他們很少直接處理觸摸事件。相反,視圖控制器通常以以下方式處理事件。

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

1.指定動作。控制器和一些視圖調用一個動作方法來響應特定交互。

2.手勢識別器。手勢識別器調用一個動作方法來響應當前手勢狀態。使用視圖控制器來處理狀態變化或響應完成的手勢。

·視圖控制器觀察系統或其他對象發送的通知。通知報告變化,同時也是視圖控制器更新狀態的一種方式。

·視圖控制器作為其他對象的數據源或代理。視圖控制器通常用于管理表的數據、集合視圖的數據。你可以使用它們作為對象的代理,例如CLLocationManager對象,發送更新的位置值到它的代理。

響應事件通常包括更新視圖的內容,這需要有這些視圖的引用。視圖控制器可以定義任何視圖的outlet。使用列表4-1中的語法來聲明你的outlet屬性。列表中的自定義類定義了兩個outlet(IBOutlet指定的關鍵字)和一個動作方法(IBOutlet指定的返回類型)。雖然動作方法響應按鈕點擊事件,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和動作到相應的視圖。連接storyboard中的outlet和動作確保黨視圖加載時他們已配置好。更多關于如何在IB中創建outlet和動作連接的方法,參見IB連接幫助(Interface Builder Connections Help)。更多關于如何處理應用中事件,參見iOS事件處理指南(Event Handling Guide for iOS)。

在運行時顯示視圖

Storyboard使加載和顯示視圖控制器的視圖變得簡單。UIKit自動從storyboard加載視圖。隨著加載過程,UIKit執行以下的任務序列:

1.使用storyboard文件中的信息實例化視圖。

2.連接所有outlet和動作。

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

4.調用視圖控制器的awakeFromNib方法。

當調用此方法,視圖控制器的特征集合為空,視圖可能不在最后的位置。

5.調用視圖控制器的viewDidLoad方法。

使用該方法添加或刪除視圖,修改布局約束,加載視圖數據。

在屏幕上顯示視圖控制器的視圖前,UIKit提供額外的機會準備這些視圖,之后顯示在屏幕上。具體說來,UIKit執行以下任務序列:

1.調用視圖控制器的viewWillAppear:方法讓它知道視圖將出現在屏幕上。

2.更新視圖布局。

3.在屏幕上顯示視圖。

4.當視圖在屏幕上調用viewDidAppear:方法。

當添加、刪除或修改視圖的大小或位置,記得添加和刪除用于這些視圖的約束。修改視圖層級的布局相關變更會導致UIKit布局混亂。在接下來的更新周期,布局引擎計算視圖的大小和位置,使用當前布局約束并將這些更改應用到視圖層級結構。

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

管理視圖布局

當視圖的大小和位置發生變化,UIKit更新視圖層級的布局信息。對于使用自動布局的視圖,UIKit使用自動布局引擎并根據當前約束使用它更新布局。UIKit還允許其他對象,例如活動展示控制器,知道布局變化,這樣它們可以做相應的回應。

在布局過程中,在幾個點上UIKit發出通知,這樣可以執行額外的布局相關任務。使用這些通知來修改布局約束或者在布局約束應用后做最后的布局調整。在布局過程中,UIKit為每個受影響的視圖控制器做如下任務:

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

2.調用視圖控制器的viewWillLayoutSubviews方法。

3.調用當前UIPresentationController對象的containerViewWillLayoutSubviews方法。

4.調用視圖控制器的根視圖的layoutSubviews方法。

該方法默認使用可用約束實現計算新布局信息。該方法遍歷視圖層級并為每個子視圖調用layoutSubviews。

5.運用計算好的布局信息到視圖。

6.調用視圖控制器的viewDidLayoutSubviews方法。

7.調用當前UIPresentationController對象的containerViewDidLayoutSubviews方法。

視圖控制器可以使用viewWillLayoutSubviews和viewDidLayoutSubviews方法執行額外更新,這些更新可能會影響布局過程。布局之前,你可以添加或刪除視圖,更新視圖的大小和位置,更新約束,或者更新其他視圖相關屬性。布局之后,可能重新加載表數據,更新其他視圖的內容,或者最后調整視圖大小和位置。

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

·使用自動布局。使用自動布局創建的約束是一種靈活和簡單的方式在不同屏幕尺寸上定位你的內容。

·利用頂部和底部布局參考線。內容布局中的參考線確保內容總是可見的。頂部位置的布局參考線把狀態欄和導航欄的高度考慮在內。同樣的,底部位置的布局參考線把tab欄或工具欄的高度考慮在內。

·當添加或刪除視圖時記得更新約束。如果動態添加或刪除視圖,記得更新相應的約束。

·當視圖控制器的視圖在動畫時,暫時刪除約束。當使用UIKit核心動畫完成視圖動畫,在動畫期間刪除約束并在動畫完成時添加約束。如果在動畫期間視圖的位置或尺寸改變,記得更新約束。

關于顯示控制器和視圖控制器結構中的作用信息,參見present和transit過程(The Presentation and Transition Process)。

有效管理內存

盡管大多數方面的內存分配由你來決定,表4-1列出了的UIViewControll方法,這些方法最有可能出現分配或釋放內存。大多數回收涉及刪除對象的強引用。刪除對象的強引用,設置指向改對象的屬性和變量為nil。

任務 方法 討論
分配視圖控制器所需的關鍵數據結構 Initialization methods 自定義initialization方法(無論是否名為init或其他)總是負責把視圖控制器對象放到一個已知狀態。使用這些方法來分配任何數據結構以確保正確的操作。
分配或加載視圖中顯示的數據 viewDidLoad 使用viewDidLoad方法加載要顯示的任何數據對象。調用此方法時,保證視圖對象存在并且處于已知狀態。
響應低內存通知 didReceiveMemoryWarning 使用該方法釋放視圖控制器所有相關對象。盡量釋放內存。
釋放視圖控制器的關鍵數據結構 dealloc 覆蓋該方法在最后清理視圖控制器類。系統自動釋放實例變量對象及類屬性,所以你不需要顯示的釋放它們。

表4-1進行分配和釋放內存的地方

官方原文地址:

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容