從程式產生 view controller 的各種方法

開發 iOS App 時,我們時常利用 storyboard & segue 設計跟切換頁面,不過我們也可以從程式產生 controller,接下來就讓我們認識從程式生成 view controller 的各種方法吧。

Image for post
Image for post

產生 storyboard 的 view controller

假設目前的 view controller 是 HomeViewController,我們想在點選 button 時產生 LoginViewController。

Image for post
Image for post
  • 從 storyboard 建立 view controller。

若 HomeViewController 是從 Main storyboard 產生,而且 LoginViewController 的畫面也在 Main storyboard,我們可透過 property storyboard 讀取到 Main storyboard,然後利用它呼叫 instantiateViewController 產生 LoginViewController。

@IBAction func tap(_ sender: Any) {
let controller = storyboard?.instantiateViewController(identifier: "LoginViewController")

}

呼叫 instantiateViewController 時傳入的 identifier 可指定我們想生成的 controller,從 storyboard 點選 controller 後,在 Storyboard ID 欄位可設定 ID。

Image for post
Image for post

值得注意的,當 App 執行時找不到擁有此 ID 的 view controller 時將造成可怕的閃退。

let controller = storyboard?.instantiateViewController(identifier: "隨便打的ID")
Image for post
Image for post
  • 利用 string interpolation 輸入 identifier。

通常 storyboard ID 會跟 controller 的類別同名,所以我們可以輸入 "\(LoginViewController.self)",減少打錯字的機率。

let controller = storyboard?.instantiateViewController(identifier: "\(LoginViewController.self)")
  • 先建立 storyboard,再從 storyboard 建立 view controller。

當想建立的 view controller 在別的 storyboard 時,我們必須先建立 storyboard,再從 storyboard 建立 view controller。

比方 LoginViewController 在 Login.storyboard。

Image for post
Image for post
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateViewController(identifier: "\(LoginViewController.self)")

生成 UIStoryboard 時,傳入的參數 name 代表 storyboard 的檔名,因此傳入 Login 表示要生成 Login.storyboard,bundle 傳入 nil 表示 Login.storyboard 在 App 本身的資料夾裡。

  • 建立開頭箭頭指到的 view controller。

controller 被開頭箭頭指到時,我們可呼叫 UIStoryboard 的 instantiateInitialViewController 建立 controller。

Image for post
Image for post
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
  • controller 的轉型和傳資料。

若想存取生成的 view controller,比方傳資料給 LoginViewController,我們還要搭配轉型,例如以下例子:

let storyboard = UIStoryboard(name: "Login", bundle: nil)
let controller = storyboard.instantiateViewController(identifier: "\(LoginViewController.self)") as! LoginViewController
controller.account = "peter pan"

ps: 轉型可用 as! 或 as?

  • 搭配 closure 初始生成的 controller。

我們也可在生成 controller 時搭配 closure 初始它的內容,詳細說明可參考以下連結。

產生 xib 的 view controller

想生成 LoginViewController,它的畫面在 LoginViewController.xib。

Image for post
Image for post

利用 controller 的類別名 + ( ) 即可生成 xib 的 view controller。

let controller = LoginViewController()

當我們以 LoginViewController() 生成 controller 時,它會尋找同名的 xib,所以它會找到 LoginViewController.xib,載入 xib 裡設計的畫面。關於產生 xib 的 view controller,其實還有其它寫法,有興趣的可參考以下連結。

產生完全由程式設計的 view controller

倘若你是個程式控,不喜歡 storyboard & xib,喜歡從程式手刻 controller 畫面的快感,那麼很簡單,搭配 controller 的 init 生成 controller 即可。

let controller = LoginViewController()

產生 segue 連接的 view controller

若我們透過 segue 連接兩個 controller,我們可利用 performSegue 產生 segue 終點的 controller,然後切換到新的 controller 頁面。

如下圖所示,segue 的起點是開啟愛情旅程的 controller,終點是 LoginViewController,segue 的 ID 是 showLogin。

Image for post
Image for post

呼叫 performSegue,傳入 ID showLogin 將產生 LoginViewController,切換到 LoginViewController。

performSegue(withIdentifier: "showLogin", sender: nil)

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store