
導航控制器幾乎是我們開發(fā)中接觸的最多的了,但是很多時候很多人還是總會把其中的 navigationBar , navigationItem 和 bar button item 等混淆,今天我們就來總結一下.
1, UINavigationBar 和 UINavigationItem
UINavigationBar:
先看看開發(fā)文檔對其的描述:
原文
The UINavigationBar class provides a control for navigating hierarchical content. It’s a bar, typically displayed at the top of the screen, containing buttons for navigating within a hierarchy of screens.The primary properties are a left (back) button, a center title, and an optional right button. You can use a navigation bar as a standalone object or in conjunction with a navigation controller object.
翻譯
UINavigationBar類提供一種對導航層級內(nèi)容的控制。它是一個欄,最典型的用法就是放在屏幕頂端,包含著各級視圖的導航按鈕。它最首要的屬性是左按鈕(返回按鈕)、中心標題,還有可選的右按鈕。你可以單獨用導航欄,或者和導航控制器一起使用。

再來看看 UINavigationItem
原文
A UINavigationItem object manages the buttons and views to be displayed in a UINavigationBar object. When building a navigation interface, each view controller pushed onto the navigation stack must have a UINavigationItem object that contains the buttons and views it wants displayed in the navigation bar. The managing UINavigationController object uses the navigation items of the topmost two view controllers to populate the navigation bar with content.
翻譯
一個UINavigationItem對象管理展示在導航欄上的按鈕和視圖。當創(chuàng)建一個導航界面的時候,每個壓入導航棧中的視圖控制器都需要一個navigation item,它包含了展示在導航欄上的按鈕和視圖。導航控制器利用最頂層的兩個視圖控制器的navigation item來提供導航欄的內(nèi)容。
實際上 navigationItem 是 navigationBar 的屬性,navigationBar 可以說是一個容器, navigationItem 是布局在其內(nèi)的,但是我們用純代碼的時候會發(fā)現(xiàn),如下,

貌似 navigationController 也有 navigationItem 屬性,這是怎么回事呢?
事實上,UINavigationController 并沒有 navigationItem 這個屬性,但是 navigationController 繼承于 viewController ,而 viewController 擁有 navigationItem 屬性,但是如果你這樣用,
self.navigationController.navigationItem.title = @"籃球";
是沒有效果的,這是因為 UINavigationController 是一個 特殊的 視圖控制器,他是視圖控制器的容器,(類似的還有 UITabBarController 和 UISplitViewController ),不能把它當做一般的 viewControlelr 使用,
但是,還有一個令人困惑的地方在于
self.navigationItem.title = @"籃球火";

同樣是對導航欄的操作,為什么一個在第一層級(UIViewController) ,另一個在其屬性navigationController的層級,
如前所述, navigationItem 是 UIViewController 的一個屬性,開發(fā)者文檔是這樣描述的
This is a unique instance of UINavigationItem created to represent the view controller when it is pushed onto a navigation controller. The first time the property is accessed, the UINavigationItem object is created. Therefore, you should not access this property if you are not using a navigation controller to display the view controller. To ensure the navigation item is configured, you can either override this property and add code to create the bar button items when first accessed or create the items in your view controller'€?s initialization code.
Avoid tying the creation of bar button items in your navigation item to the creation of your view controller'€?s view. The navigation item of a view controller may be retrieved independently of the view controller'€?s view. For example, when pushing two view controllers onto a navigation stack, the topmost view controller becomes visible, but the other view controller'€?s navigation item may be retrieved in order to present its back button.
The default behavior is to create a navigation item that displays the view controller'€?s title.
翻譯
它是UINavigationItem一個獨特的實例。當視圖控制器被推倒導航控制器中時,它來代表這個視圖控制器。當?shù)谝淮卧L問這個屬性的時候,它會被創(chuàng)建。因此,如果你并沒有用導航控制器來管理視圖控制器,那你不應該訪問這個屬性。為確保navigation item 已經(jīng)配置,你可以在視圖控制器初始化時,重寫這個屬性、創(chuàng)建bar button item。
要避免在創(chuàng)建視圖控制器的視圖時,創(chuàng)建bar button item。視圖控制器的這個屬性——navigationItem,它的恢復(生命周期——作者注),可能獨立于視圖控制器的視圖。為什么會這樣?舉例來說,當把兩個視圖控制器壓到導航棧中,最頂層的視圖控制器是可見的,但另一個視圖控制器的navigation item 可能是活躍狀態(tài)(此時,隱藏的視圖控制器的視圖肯定是不活躍的,所以,這個時候navigation item 是獨立于視圖控制器的視圖的——作者注),因為它要呈現(xiàn)其返回按鈕。
默認行為是創(chuàng)建一個navigation item 來展示視圖控制器的標題。
總結一下,如果把導航控制器(navigationController)比作一個劇院,那導航欄(navigationBar)就相當于舞臺,舞臺必然是屬于劇院的,所以,導航欄是導航控制器的一個屬性。視圖控制器(UIViewController)就相當于一個個劇團,而導航項(navigationItem)就相當于每個劇團的負責人,負責與劇院的人接洽溝通。顯然,導航項應該是視圖控制器的一個屬性。雖然導航欄和導航項都在做與導航相關的事情,但是它們的從屬是不同的。也就是說 導航欄 從屬于 導航控制器, 導航項 從屬于 視圖控制器
導航欄(navigationBar)相當于負責劇院舞臺的布景配置,導航項(navigationItem)則相當于協(xié)調(diào)每個在舞臺上表演的演員(bar button item,title 等等),每個視圖控制器的導航項可能都是不同的,可能一個右邊有一個選擇照片的bar button item,而另一個視圖控制器的右邊有兩個bar button item。