Storyboard 是在 iOS 5 SDK 中才出現的新名詞,它其實就是原本的 Xib 檔案(Interface Builder),用來製作介面排版方面的工具,當然在 Storyboard 裡也多了很多應用的元件,其中 Storyboard Segue 可以讓你幾乎連程式碼都不用寫,就輕鬆完成兩個 UIViewController 的切換工作,以下是我們的示範。
首先在開啓新專案時選擇 Single View Application 來簡化流程,可以少製作一個 UIViewController 與它對應的 class 檔,如果各位有需要當然也可以開啓完全空白的乾淨的新專案,再自行加入 storyboard 與 UIViewController。
接著來到專案下的 storyboard 畫面,從右下方的元件庫中拉一個 UIViewController 到 storyboard 中,並且分別對兩個 UIViewController 做介面上的設計:增加 Navigation Bar 來辨識彼此,與一個用來做頁面切換按鈕,如下圖。
我們希望在頁面 1 按下前往頁面 2 的按鈕時,畫面能切換至頁面 2,之後也能以同樣的方法返回頁面 1,為了達到目的,必須使用 Storyboard Segue 元件將兩個 UIViewController,給連起來,由於 Storyboard Segue 是動態產生的,所以並不會出現在元件 Storyboard 的元件庫中。
產生 Storyboard Segue 的方法常簡單,就如同替介面元件和程式碼做連結的拖曳方式一樣的直覺,使用滑鼠右鍵將頁面 1 內的按鈕拖曳連結至頁面 2 ,並選擇 Model 做連結,Storyboard Segue 就會自動連結兩個 UIViewController,如下圖。
現在你可以用模擬器執行看看,在 Segue DEMO 頁面 1 按下前往頁面 2 的按鈕時,畫面就會切換至頁面 2,如果想要使用不同的換頁效果,可以在 Storyboard Segue 中的 Transition 屬性做修改,範例中所使用的是翻頁 Partial Curl 效果。
下來就是從頁面 2 「返回」頁面一,在這裡我們特別強調「返回」而不是前往,一個錯誤的做法,是按照上面的步驟將頁面 2 的按鈕拖曳連結至頁面一的 Model,使整個 Storyboard 的佈局如下圖。
如果你按照這樣的設計方式來執行,你會發現兩個頁面的確可以互相切換,功能上是正確,但是背後的意義卻大不相同,而且在多次切換後很有可能創造過多的 UIViewController 實體,這樣做畫面每次都會朝同樣的方向來做切換的效果,每次都會建立一個新的 UIViewController 實體來使用。
我想大家應該都猜到正確的做法應該是在頁面 2 的程式碼中使用 dismissModalViewControllerAnimated: 方法,或是 dismissViewControllerAnimated:completion: 方法來解散頁面 2,並返回先前的頁面。
替專案新增一個 UIViewController 的 Subclass,我們命名為 Page2ViewController,並取消 With XIB for user interface(我們已經建立了它的介面),接著在其中實作一個按鈕事件來解散頁面,程式碼如下。
- (IBAction)returnToFirstPage:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{}];
}
最後回到專案下的 Storyboard,將我們新產生的 UIViewController 與 Page2ViewController 做連結,連結的方式是在 UIViewController 的屬性中選擇對應的 class 檔,如下圖,之後將其按鈕元件與 Page2ViewController 的按鈕事件做連結即可。
現在再用模擬器執行看看,按下頁面 2 中的按鈕,畫面會以相反的方向的切換效果來返回頁面 1。
請問可以用程式碼去切換頁面嗎?
回覆刪除而不要用按鈕和拉線的方式
為什麼多了這行[self dismissViewControllerAnimated:YES completion:^{}];
回覆刪除就沒辦法回到page1??
我不是很懂你的意思,這一行程式碼的意思就是解散目前的 ViewController
刪除如果你在頁面二按下按鈕,執行上述程式碼,並沒有回到頁面一,那是去哪了?
1到2 ok
刪除2到1 執行後程式 就崩潰了當機
註解掉就回到第一種沒用dismiss是ok的
你可能在 storyboard Segue上已經自動做好連結了,如過是這樣的確會有這種情強發生,
刪除因為你在按下按鈕時 storyboard Segue 已經將頁面二釋放掉了,所以自然沒有 instance 去 dismiss,
如果是這樣,那也就不需要加上那一行來釋放,不過以上述的範例來說如果使用 storyboard Segue 做釋放頁面二,會在多產生一個頁面一的 instance..造成無窮迴圈..
所以要先把2→1的storyboard Segue刪掉 才會出現dismiss效果
刪除感謝 指導 我剛剛試ok了
嗯嗯
刪除不用客氣!
牛奶你好:
回覆刪除我看到一個程式是利用xib去寫的然後在delegate生成view,但是我想把它套用到storyboard有哪些地方是我需要改變的.
您好:
刪除不用改變任何東西,storyboard 一次可以在介面上設計多個 UIViewController 也能表達他們彼此間的關係,而 Xib 僅能有單一一個,
如果你把 xib 的概念直接套用到 storyboard 是可以行的,但是反之則會出現 association 的問題。
牛奶你好:
刪除那如果他在delegate檔裡面有 alloc init viewController ,我要怎麼轉換它變成在storyboard可以執行的呢。是要拉出outlet嗎?
您好:
刪除完全一樣意思,只是附檔名由xib換成storyboard,你也可以把整個storyboard當做xib使用,只放置一個UIViewController,其他的都動態產生。
牛奶你好:
刪除真的很抱歉我是初學者,對於你的意思我還是有點不了解,程式碼如下:
window = [[UIwindow alloc]initWithFram:[[UIScreen mainScreen] bounds]];
TokenFieldExampleViewController * viewController = [[TokenFieldExampleViewController alloc] init];
我程式碼到這裡就會出現"_OBJC_CLASS_$_TITokenField",referenced from:......
希望大大可以給我解答 謝謝:(
您好:
刪除大家都有當初學者的時候,我建議您可以先用 single view application 的樣板開啟專案,比較一下兩者不同,你就會知道了。
你可以參考下面的網站,我覺得他的問題跟您蠻像的。
http://stackoverflow.com/questions/8705815/iphone-ios5-storyboard-how-to-load-a-uiviewcontroller-with-a-custom-xib-file
加油!
牛奶你好:
回覆刪除謝謝你,這真的是一個很棒的網站,那如果他沒有用storyboard也沒有使用xib而是在delegate裡面生成view我一樣可以用這個方法嗎?
您好:
刪除一樣可以,如果你想要連動最一開的 ViewController 都是動態產生,你可以在 delegate.m 下設定中斷點,了解一下如何運作。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 函式會在應用程式ㄓ 準備完成時被觸發,你也可以在此函式中做介面設計,或是產生新的ViewController。
下面這個頁面是使用空白專案開始,到 Single View Application 的製作過程,你可以在一開始的地方看到,上述的函式是如何格式化現有的視窗畫面(白色底)。
http://furnacedigital.blogspot.tw/2012/01/empty-application-single-view.html
牛奶你好~
回覆刪除請問使用UIAlertView這個元件,在彈出視窗的按鈕能有方法能做換頁的功能嗎?
您好:
刪除你這樣問我一定都會說可以的阿,只是這樣就不需要透過 Storyboard Segue 來換頁面,因為你的UIAlertView一定是動態產生的。
必須注意幾點:
-將UIAlertView中的按鈕做好事件的連結,在按下按鈕時所要觸發的函式。
-被觸發的函式中建立新的 ViewController 來做切換,這邊你可以會需要使用到delegate的技巧來傳遞參數。
牛奶你好:
回覆刪除想請問一下我有一個主View加4個ViewController,這5個View裡面皆有個滑動菜單,菜單裡面有四個按鈕,按下後分別會切換到ViewControllerA,B,C,D
我是使用[self presentViewController:ViewControllerA animated:NO completion:^{}];來切換
第一次(從主View連到其他ViewController)可以正常運作
但第一次過後(從非主View連到其他View)卻會崩潰
請問一下是我哪邊做錯了嗎
您好:
刪除我覺得不需要這麼多的 ViewController ,如果你的配置上都一樣,可以考慮使用一個就好,其他的則動態產生或是直接替換主要的內容。
另外崩潰的原因推測與找不到instance有關,你可以試著將 dismissViewControllerAnimated 加入看看,因為這樣可以確保你返回正確的ViewController,例如 :主畫面 -->ViewController A-->ViewController C
在實作上可以寫成
主畫面 --(按下前往頁面A)-->presentViewController: ViewController A
--(按下前往頁面C)--> dismissViewControllerAnimated (先回到主畫面) ---->presentViewController:ViewController C