前言:蘋果官方是推薦我們將所有的UI都使用Storyboard去搭建,Storyboard也是一個很成熟的工具了。使用Storyboard去搭建所有界面,我們可以很迅捷地搭建出復雜的界面,也就是說能為我們節省大量的時間。我們還可以很直觀地看出各個界面之間的關系,修改起來也很方便。將來如果遇到需要作修改的地方,我們只需要找到相對應的Storyboard就可以了,比起以前來說,快捷了不少。
我會在本文的最後附上Demo,可以幫助你們有更直觀的理解,有需要的人可以去下載運行一下。
另外,建議大家實驗每一種方法時,先清空界面上的內容,以避免出現錯誤。因為初學者很容易使得界面上有殘留,具體的這裡就不說明了。接下來,讓開始我們的Storyboard之旅吧!
一、使用Storyboard進行跳轉
1)純Storybard界面操作
2)使用代碼進行跳轉
二、Storyboard界面傳值
1)使用prepareForSegue方法進行跳轉:
2)Storyboard Id跳轉
我們在Storyboard上放置一個按扭,在按扭上方點擊並按住“右鍵”不放,拖動到跳轉的下一個界面上。
松開右鍵後,會有一個黑色透明的彈出框,選擇跳轉的方式:
從這裡可以看到,界面和界面之間多了一條線連接,如下圖:
我們可以在Xcode右邊的工具欄看到,我們剛剛的連線操作(現在可以運行項目了):
我們把剛剛的連線刪除掉,如下圖所示:
新建一個繼承於UIViewController的類CodeViewController:
選中按扭所在的界面,設置它的類文件,默認都是繼承於UIViewController,如下圖所示:
我們把它改成剛剛新建的類“CodeViewController”,如下圖所示:
把界面縮小(你可以在空白的地方雙擊一下,或者右鍵選擇縮放比例),這次我們不是直接使用“按扭”連接界面,而是進行界面和界面之間的連線,如下圖所示:
注意:100%的縮放是不能進行界面和界面之間的連線!
之後的操作和前面的一致,為了容易理解,我還是貼一下圖:
選中“這條線”,在Storyboard Segue的Identifier指定一個標識符,後面我們會用到:
這時我們需要為按扭添加一個事件,為此需要同時顯示Storyboard和.m文件,操作如下:
創建事件的操作和之前連線的操作一樣:
為這個事件創建一個名字,然後點擊Connect:
在事件裡添加如下代碼,把剛連線的Identifier傳進去,sender一般為self:
[self performSegueWithIdentifier:@EasyCode sender:self];
這樣,就可以成功跳轉了。
我們創建兩個類,PrepareViewController和ReceiveViewController
然後在Storyboard上新建兩個ViewController,把兩個界面連接起來。操作步驟和上方(代碼跳轉)的相同,這次我們把連線的Identifier定義為“SendValue”:
有按扭的界面的類設置為PrepareViewController,如下圖所示:
選擇第二個界面,設置繼承的類為ReceiveViewController:
ReceiveViewController.h:
#import@interface ReceiveViewController : UIViewController @property (strong, nonatomic) NSString *name; @property (assign, nonatomic) int age; @end
ReceiveViewController.m,當然是要輸出一下啦,不然怎麼知道傳值有沒有成功:
#import ReceiveViewController.h @interface ReceiveViewController () @end @implementation ReceiveViewController - (void)viewDidLoad { [super viewDidLoad]; NSLog(@name is %@, age is %d, _name, _age); } @end
PrepareViewController.m文件:
#import PrepareViewController.h #import ReceiveViewController.h @interface PrepareViewController () @end @implementation PrepareViewController - (IBAction)goAction:(id)sender { // 根據指定線的ID跳轉到目標Vc [self performSegueWithIdentifier:@SendValue sender:self]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // segue.identifier:獲取連線的ID if ([segue.identifier isEqualToString:@SendValue]) { // segue.destinationViewController:獲取連線時所指的界面(VC) ReceiveViewController *receive = segue.destinationViewController; receive.name = @Garvey; receive.age = 110; // 這裡不需要指定跳轉了,因為在按扭的事件裡已經有跳轉的代碼 // [self.navigationController pushViewController:receive animated:YES]; } } @end
可以成功接收到值啦(大功告成):
2)Storyboard Id跳轉
繼續拖兩個純淨的界面(VC)到Storyboard上,第一個界面也是放上一個UIButton:
IdViewController是我剛新建出來的類,接收值的界面用回ReceiveViewController類,指定界面繼承的類為(IdViewController、ReceiveViewController)
第二個界面設置Storyboard id為“IdReceive”,後面跳轉會用到:
IdViewController.m
- (IBAction)action:(id)sender { // 獲取指定的Storyboard,name填寫Storyboard的文件名 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@Main bundle:nil]; // 從Storyboard上按照identifier獲取指定的界面(VC),identifier必須是唯一的 ReceiveViewController *receive = [storyboard instantiateViewControllerWithIdentifier:@IdReceive]; receive.name = @GC; receive.age = 10; [self.navigationController pushViewController:receive animated:YES]; }
可以運行程序了,能夠成功接收到值,成功!
小結:你們能否看出各個方法的優點和缺點?現在沒發現不要緊,當你們以後遇上真正需要的時候,優缺點就很容易知道了,這也算是留給你們思考的一件事情吧。
題外話:
有部分人是不同意使用Storyboard的,他們的的觀點如下:
1)Storyboard出現的錯誤不能調試,往往使得他們開發緩慢
2)對於多人開發,版本管理會比較復雜
3)Storyboard經常無緣無故出現問題!使得他們很頭痛!
首先,對於第1點和第3點的回答:Storyboard出現的錯誤往往是可以避免的。其次,Storyboard不會無緣無故出現問題,如果真的出現問題了,往往是開發者的操作不當成造成的。我為什麼這樣說?
因為我以前也遇到很多因Storyboard引起的錯誤,那時候的我也經常怨Storyboard。但隨著對Storyboard越來越熟悉後,我才發現,以前全都是因為自己操作不當,而造成程序的崩潰。
第2點:多人開發,可以區分模塊開發,每個人負責的模塊都不相同,不一定要所有人的都開發同一個模塊。當然,有特殊情況的我也不知道,所以說這個需要根據項目的大小和復雜度去判定的。
花了一個下午去寫這一篇文章,感覺好累好累。
希望這篇文章能對大家所幫助,謝謝。