UINavigationController
UINavigationController 類實現(xiàn)了一個用于管理分層內(nèi)容導(dǎo)航的專用視圖控制器。 該導(dǎo)航界面可以有效地呈現(xiàn)您的數(shù)據(jù),并使用戶更容易瀏覽該內(nèi)容。 您通常按照原樣使用此類,但您也可以使用子類來自定義類的行為。
預(yù)覽
導(dǎo)航界面呈現(xiàn)的屏幕通常會模擬您的數(shù)據(jù)層次結(jié)構(gòu)。 在層次結(jié)構(gòu)的每個級別中,您提供一個適當(dāng)?shù)钠聊唬ㄓ勺远x視圖控制器管理)來顯示該級別的內(nèi)容。 圖1顯示了iOS模擬器中“設(shè)置”應(yīng)用程序提供的導(dǎo)航界面的示例。 第一個屏幕向用戶顯示包含首選項的應(yīng)用程序列表。 選擇應(yīng)用程序會顯示該應(yīng)用程序的各個設(shè)置和設(shè)置組。 選擇組會產(chǎn)生更多設(shè)置等等。 除了根視圖之外,導(dǎo)航控制器提供一個后退按鈕,以允許用戶返回到上一層次結(jié)構(gòu)。

導(dǎo)航控制器對象使用(由視圖控制器數(shù)組表示的)導(dǎo)航堆棧(navigation stack)管理當(dāng)前顯示的屏幕。 數(shù)組中的第一個視圖控制器是根視圖控制器。 數(shù)組中的最后一個視圖控制器是當(dāng)前正在顯示的視圖控制器。 您可以使用 segue 或使用此類中的方法從堆棧中添加和刪除視圖控制器。 用戶還可以使用導(dǎo)航欄中的后退按鈕或使用左側(cè)滑動手勢來移除最上面的視圖控制器。
導(dǎo)航控制器管理界面頂部的導(dǎo)航欄和界面底部的可選工具欄。 導(dǎo)航欄始終存在,并由導(dǎo)航控制器本身管理,導(dǎo)航控制器本身使用導(dǎo)航堆棧上的視圖控制器提供的內(nèi)容來更新導(dǎo)航欄。 當(dāng) toolbarHidden 屬性為 NO 時,導(dǎo)航控制器將以最上層視圖控制器提供的內(nèi)容類似地更新工具欄。
導(dǎo)航控制器使用委托(delegate)對象協(xié)調(diào)其行為。 委托對象可以覆蓋視圖控制器的推送或彈出,提供自定義的轉(zhuǎn)換動畫,并指定導(dǎo)航界面的首選方向。 您提供的委托對象必須遵守 UINavigationControllerDelegate 協(xié)議。
圖2顯示了導(dǎo)航控制器與其管理對象之間的關(guān)系。 使用導(dǎo)航控制器的指定屬性訪問這些對象。

導(dǎo)航控制器視圖
導(dǎo)航控制器是一個容器視圖控制器——也就是說,它將其他視圖控制器的內(nèi)容嵌入到其中。 您可以從其 view 屬性訪問導(dǎo)航控制器的視圖。 此視圖包含導(dǎo)航欄,可選的工具欄以及與最上層視圖控制器對應(yīng)的內(nèi)容視圖。 圖3顯示了如何組合這些視圖來呈現(xiàn)整個導(dǎo)航界面。 (在該圖中,導(dǎo)航界面進(jìn)一步嵌入到 tab bar 界面中。)雖然導(dǎo)航欄和工具欄視圖的內(nèi)容發(fā)生變化,但視圖本身不會。 實際更改的唯一視圖是導(dǎo)航堆棧上最上層視圖控制器提供的自定義內(nèi)容視圖。

注意
在iOS 7及更高版本中,因為內(nèi)容視圖在導(dǎo)航欄下方,您必須在設(shè)計視圖控制器內(nèi)容時考慮該空間。
導(dǎo)航控制器管理導(dǎo)航欄和可選導(dǎo)航工具欄的創(chuàng)建,配置和顯示。 允許自定義導(dǎo)航欄的外觀相關(guān)屬性,但是千萬不要直接更改其 frame,bounds或 alpha值。 如果您將 UINavigationBar 子類化,則必須使用initWithNavigationBarClass:toolbarClass: 方法初始化導(dǎo)航控制器。 要隱藏或顯示導(dǎo)航欄,請使用navigationBarHidden 屬性或 setNavigationBarHidden:animated: 方法。
導(dǎo)航控制器使用與導(dǎo)航堆棧上的視圖控制器相關(guān)聯(lián)的導(dǎo)航項目對象(UINavigationItem 類的實例)動態(tài)構(gòu)建導(dǎo)航欄的內(nèi)容。 要定制導(dǎo)航欄的整體外觀,請使用 UIAppearance API。 要更改導(dǎo)航欄的內(nèi)容,您必須配置自定義視圖控制器的導(dǎo)航項。 有關(guān)導(dǎo)航項的更多信息,請參閱 UINavigationItem。
更新導(dǎo)航欄(Navigation Bar)
每次頂層的視圖控制器更改時,導(dǎo)航控制器會相應(yīng)地更新導(dǎo)航欄。 具體地,導(dǎo)航控制器更新顯示在三個導(dǎo)航欄位置中的每一個的欄按鈕項:左,中,右。 按鈕項是 UIBarButtonItem 類的實例。 您可以使用自定義內(nèi)容創(chuàng)建按鈕項,或根據(jù)需要創(chuàng)建標(biāo)準(zhǔn)系統(tǒng)按鈕項。
導(dǎo)航欄的 tint 由導(dǎo)航欄本身的屬性控制。 使用 tintColor 屬性更改導(dǎo)航欄中 Item 的顏色,并使用 barTintColor 屬性來更改導(dǎo)航欄本身的顏色。 導(dǎo)航欄不會從當(dāng)前顯示的視圖控制器中繼承其 tintColor。
有關(guān)導(dǎo)航欄的更多信息,請參閱 UINavigationBar。 有關(guān)如何創(chuàng)建條形按鈕項的更多信息,請參閱 UIBarButtonItem。
The Left Item
除了導(dǎo)航堆棧上的根視圖控制器之外,導(dǎo)航欄左側(cè)的 Item 可以導(dǎo)航返回到上一個視圖控制器。 這個最左邊按鈕的內(nèi)容確定如下:
- 如果新創(chuàng)建的最頂層視圖控制器具有自定義的左欄按鈕Item,則顯示該Item。 要指定自定義左欄按鈕,請設(shè)置視圖控制器導(dǎo)航項目的
leftBarButtonItem屬性。 - 如果最頂層視圖控制器沒有自定義左欄按鈕項,但是上一個視圖控件的導(dǎo)航項在其
backBarButtonItem屬性中有一個對象,導(dǎo)航欄將顯示該項。 - 如果任何一個視圖控制器都沒有指定自定義導(dǎo)航欄欄按鈕項,則使用默認(rèn)的后退按鈕,并將該按鈕的標(biāo)題設(shè)置為上一個視圖控制器的
title屬性的值,即視圖控制器下一級堆棧。 (如果導(dǎo)航堆棧中只有一個視圖控制器,則不顯示后退按鈕。)
注釋
假設(shè)通過VC1
pushVC2,那么如果設(shè)置VC1.navigationItem.backBarButtonItem就會顯示在VC2的左上角返回按鈕;如果再設(shè)置VC2.navigationItem.leftBarButtonItem則會覆蓋VC1的設(shè)置;如果VC1和VC2都沒有設(shè)置,則會顯示默認(rèn)的backBarButtonItem,它的標(biāo)題是VC1的title。
注意
如果后退按鈕的標(biāo)題太長而不能放在可用空間中,則導(dǎo)航欄可以將字符串“后退”替換實際的按鈕標(biāo)題。 只有后退按鈕由前一個視圖控制器提供時,導(dǎo)航欄才會執(zhí)行此操作。 就算新的頂級視圖控制器自定義了左欄返回按鈕項 - 該導(dǎo)航項的
leftBarButtonItem或leftBarButtonItems屬性中的對象 - 導(dǎo)航欄也不會更改按鈕標(biāo)題。
The Middle Item
導(dǎo)航控制器更新導(dǎo)航欄的中間項,如下所示:
- 如果新的頂級視圖控制器具有自定義標(biāo)題視圖,則導(dǎo)航欄將顯示該視圖以替代默認(rèn)標(biāo)題視圖。 要指定自定義標(biāo)題視圖,請設(shè)置視圖控制器導(dǎo)航項的
titleView屬性。 - 如果沒有設(shè)置自定義標(biāo)題視圖,則導(dǎo)航欄將顯示包含視圖控制器默認(rèn)標(biāo)題的標(biāo)簽。 該標(biāo)簽的字符串通常從視圖控制器本身的
title屬性獲取。 如果要顯示與視圖控制器相關(guān)的標(biāo)題不同的標(biāo)題,請改為設(shè)置視圖控制器導(dǎo)航項的標(biāo)題屬性。
The Right Item
導(dǎo)航控制器更新導(dǎo)航欄的右側(cè)項,如下所示:
- 如果新的頂級視圖控制器具有自定義右鍵按鈕項目,則顯示該項目。 要指定自定義右鍵按鈕項目,請設(shè)置視圖控制器導(dǎo)航項目的
rightBarButtonItem屬性。 - 如果沒有指定自定義的右欄按鈕項目,則導(dǎo)航欄在該欄的右側(cè)不顯示。
展示Toolbar
導(dǎo)航控制器對象在其視圖層次結(jié)構(gòu)中管理可選工具欄(Toolbar)。顯示時,此工具欄從活動視圖控制器的toolbarItems 屬性中獲取其當(dāng)前的一組項目。當(dāng)前視圖控制器更改時,導(dǎo)航控制器更新工具欄項目以匹配新的視圖控制器,在適當(dāng)時將新項目動畫化。
導(dǎo)航工具欄默認(rèn)隱藏,但您可以通過調(diào)用導(dǎo)航控制器對象的 setToolbarHidden:animated:方法來顯示導(dǎo)航界面。如果不是所有的視圖控制器都支持工具欄項,您的委托對象可以調(diào)用此方法在隨后的推送和彈出操作期間切換工具欄的可見性。要使用自定義 UIToolbar 子類,請使用 initWithNavigationBarClass:toolbarClass:方法初始化導(dǎo)航控制器。如果您使用自定義工具欄和導(dǎo)航欄子類來創(chuàng)建導(dǎo)航控制器,請注意,在將導(dǎo)航控制器顯示在屏幕上之前,請注意您需要按下并設(shè)置視圖控制器。
適應(yīng)不同環(huán)境
導(dǎo)航界面在水平緊湊和水平正常的環(huán)境中保持不變。 當(dāng)在兩個環(huán)境之間切換時,只有導(dǎo)航控制器視圖的大小發(fā)生變化。 導(dǎo)航控制器不會更改其視圖層次結(jié)構(gòu)或其視圖的布局。
當(dāng)在導(dǎo)航堆棧上配置視圖控制器之間的 segues 時,標(biāo)準(zhǔn)的 Show 和 Show Detail 行為如下:
- Show segue—導(dǎo)航控制器將指定的視圖控制器 push 入其導(dǎo)航堆棧。
- Show Detail segue—導(dǎo)航控制器以模態(tài)方式呈現(xiàn)指定的視圖控制器。
其他 segues類型的行為不變。
Interface Behaviors
導(dǎo)航控制器為其界面支持以下行為:
-
Supported interface orientations (支持的接口方向) - 確定支持的接口方向時,導(dǎo)航控制器對象不會在其導(dǎo)航堆棧上查看視圖控制器。 在iPhone上,導(dǎo)航控制器支持除肖像上下顛倒之外的所有方向。 在iPad上,導(dǎo)航控制器支持所有方向。 如果導(dǎo)航控制器具有委托對象,則委托可以使用
navigationControllerSupportedInterfaceOrientations:方法指定一組不同的支持方向。 -
Presentation context (演示文稿上下文) - 導(dǎo)航控制器定義了模態(tài)呈現(xiàn)視圖控制器的呈現(xiàn)上下文。 當(dāng)模態(tài)轉(zhuǎn)換樣式為
UIModalPresentationCurrentContext或UIModalPresentationOverCurrentContext時,導(dǎo)航堆棧中的視圖控制器的模態(tài)呈現(xiàn)覆蓋整個導(dǎo)航界面。
保存狀態(tài)
在iOS 6及更高版本中,如果為此視圖控制器的 restoreIdentifier 屬性分配值,則會嘗試在其導(dǎo)航堆棧上保留子視圖控制器。 導(dǎo)航控制器從堆棧底部開始向上移動,對每個具有有效恢復(fù)標(biāo)識符字符串的視圖控制器進(jìn)行編碼。 在下一個啟動周期中,導(dǎo)航控制器將保留的視圖控制器按照保留的順序恢復(fù)到導(dǎo)航堆棧。
推送到導(dǎo)航堆棧的子視圖控制器可能使用相同的恢復(fù)標(biāo)識符。 導(dǎo)航控制器自動存儲附加信息,以確保每個孩子的恢復(fù)路徑是唯一的。