從程式產生 view controller 的各種方法
開發 iOS App 時,我們時常利用 storyboard & segue 設計跟切換頁面,不過我們也可以從程式產生 controller,接下來就讓我們認識從程式生成 view controller 的各種方法吧。
產生 storyboard 的 view controller
假設目前的 view controller 是 HomeViewController,我們想在點選 button 時產生 LoginViewController。
- 從 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。
值得注意的,當 App 執行時找不到擁有此 ID 的 view controller 時將造成可怕的閃退。
let controller = storyboard?.instantiateViewController(identifier: "隨便打的ID")
- 利用 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。
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。
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。
利用 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。
呼叫 performSegue,傳入 ID showLogin 將產生 LoginViewController,切換到 LoginViewController。
performSegue(withIdentifier: "showLogin", sender: nil)