[CS193P] 第七堂課摘要及心得筆記

上次的筆記中我們提到了View Controller的基礎,以及如何建立自己的View Controller。在這一次的課程內容中,我們將學習到如何使用UIKit所提供的View Controllers來幫助我們建立程式的導覽。
評論
評論

上次的筆記中我們提到了 View Controller 的基礎,以及如何建立自己的 View Controller。在這一次的課程內容中,我們將學習到如何使用 UIKit 所提供的 View Controllers 來幫助我們建立程式的導覽。

第七次的課堂中,主要涵蓋了一下幾個主題:

  1. Navigation Controller
  2. Controller 間的資料傳遞
  3. 自訂導覽列
  4. Tab Bar Controller
  5. 結合兩種形式

Navigation Controller

在上一次的 iPhone 開發課程筆記 中我們談到了 View Controller 的建立方法以及概念,概括而言,View Controller 在 iPhone 程式當中扮演著主幹的角色,負責銜接 View 和 Model。

而在上回筆記中的後段,我們也曾經談過我們可以透過 UIKit 中所提供的 View Controller 來銜結我們自己的 View Controller,建立出整個程式的動線。而 Navigation Controller 就是常用的一種。很多 iPhone 的程式中都有 Navigation Controller,像是當我們在專輯列表中選擇了某一張專輯,隨集會從螢幕左邊帶入歌曲的列表,我們也可以點左上角的返回按鈕回到專輯列表,這樣的導覽模式就是 Navigation Controller。

而 Navigation Controller 的畫面就如下所示,在中間顯示了目前在 Stack 最上端的 Controller 的 View,在上面則是這個 Controller 的 title,左上角的上一頁按鈕則是前一個 Controller 的 title。

就實做上來說,Navigation Controller 下面包含了許多需要顯示的 View Controllers,用 Stack 的方式集合在一起。當我們需要換頁的時候,我們只需要 push 一個 View Controller 進去,而需要回到上一頁則是透過 pop 一個 View Controller 來達成。

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; // 換到新的 Controller - (UIViewController *)popViewControllerAnimated:(BOOL)animated; // 回到上一個 Controller - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated; // 整組換掉,在 iPhone OS 3.0 後加入

上面這幾個方法中,(BOOL)animated 這個參數決定了換頁時是否會有動畫的效果。在大多數的情況下,我們當然想要顯示換頁的效果,但是當程式剛啟動、初始化時,在加入第一個 VIew Controller 的時,我們就不需要動畫的效果。

值得一提的是,我們一般很少會直接呼叫 pop 方法,因為在使用者按下左上角的退回按鈕時就會自動呼叫這個方法了。

在投影片的第 19 頁和 22 有分別介紹如何初始化一個 Navigation Controller 以及如何加入新的 Controller,有興趣的讀者還請參考。比較需要注意的是,當我們初始化完 NavigationController 之後,要記得把 NavigationController 的 view 加入到 window 的 subview 中,否則畫面上不會顯示。

Controller 間的資料傳遞

在程式的進行中,會有很多 Controller 被建立或是移除,那我們要怎麼讓這些 Controller 能夠互相溝通呢?用下圖的例子作為舉例,List Controller 包含了所有資料的列表,而 Detail Controller 則是會顯示被選取道的資料內容。

由 List Controller 傳遞資料到 Detail Controller 的方法相當簡單,由於後者的初始化會由前者進行,所以只要定義好初始化的參數就沒問題了。然而,要從後者傳遞給前者,我們會使用 Delegate 的方式,也就是建立一組 protocol,讓 List Controller 去實做,當 Detail Controller 需要傳遞訊息時則呼叫 List Controller 的對應方法就行了。

自訂導覽列

Navigation Controller 所產生的螢幕畫面最上方有條導覽列,包含了標題還有一些按鈕,我們可以透過修改 UINavigationItem 來達成我們想要的效果。每個 View Controller 都包含一個 UINavigationItem,然而只有在 Navigation Controller 的 Stack 最上方的才會被顯示。

如果我們修改標題的話,並不需要修改 UINavigationItem,因為 View Controller 中就有一個 title 的 property,UINavigationItem 會自動繼承這個 property 來顯示。

至於按鈕的部份,UIKit 提供了三種不同的按鈕,分別是字串的顯示、圖片的顯示和系統內建的按鈕。而這些按鈕就如同一般按鈕一樣,用的是 target-action 的概念,在投影片的第 50 到 59 頁中有範例的程式碼,讀者可以直接複製使用。

此外,我們也可以在原本 title 的地方顯示一個 View 而非單純的字串,只要將 self.navigationItem.titleView 指定為想要顯示的 View 即可。

最後,因為退回按鈕是直接使用 NavigationController 中 Stack 的前一項 Controller 的 title,有時候會出現文字過長的情形,請參考投影片的第 66 頁的作法,另行設定一個按鈕替換,就可以解決這個問題了。

Tab bar Controller

談完了 NavgationController,我們當然也沒有忘記 TabBarController。TabBarController 就是我們在各個 App 中看到下方有一排按鈕,每個按鈕分別會切換到不同的 View Controller。

在投影片 78 頁中可以看到,建立 TabBarController 的作法跟 NavigationController 相同,一樣要記得加入到 window 的 subviews 當中,才會在螢幕上顯示。

如同 UINavigationItem 一樣,每個 View Controller 也包含了一個 UITabBarItem 物件,由文字及圖案組成,而 UIKit 也提供了一些系統內建的按鈕可以使用。建立按鈕的程式碼在投影片的第 84 和 87 頁,大家還多多參考。要注意的是,除了用程式建立 UITabBarItem 之外,我們也可以透過 Interface Builder 來建立,相對是比較容易、簡單。

結合兩種形式

最後,我們也可以結合以上兩種形式,由 Tab Bar Controller 作為基礎,加入 Navigation Controller 或是其他自訂的 View Controller,這樣一來就形成了一般常見的 iPhone 應用程式架構了。

結論

在這次的課程中,我們學習到了兩種導覽用的 View Controlles 的使用方法。在下一次的內容中,我們將看到如何透過 Table View Controller 來顯示大量資料,並且處理捲動的效果,還請各位讀者敬請期待!

參考資源