Storyboard 系列文章
[iOS] Storyboard (1) -- 入門:API 篇
[iOS] Storyboard (2) --入門:約束篇
[iOS] Storyboard (3) -- 使用:常用Tips
[iOS] Storyboard (4) -- 實踐:問題總結(jié)
[iOS] Storyboard (4) -- 實踐:UIScrollView
[iOS] Storyboard (4) -- 實踐:UICollectionView
在 iOS
中有兩種可以實現(xiàn)的可視化編程的方法,一種是StoryBoard
,俗稱 sb
,是 iOS
下可視化編程的方式之一,另一種是 XIB
。這里主要介紹和 StoryBoard
相關的一些 API
。
1. UIStoryboard
UIStoryboard
的 API
很簡單,主要有一個初始化方法,和兩個實例方法:
// 通過 Storyboard ID 來獲取 Storyboard 實例
+ (UIStoryboard *)storyboardWithName:(NSString *)name bundle:(nullable NSBundle *)storyboardBundleOrNil;
// 獲取當前 Storyboard 實例的初始化控制器
- (nullable __kindof UIViewController *)instantiateInitialViewController;
// 通過 Storyboard ID 來獲取當前 Storyboard 中的控制器實例
- (__kindof UIViewController *)instantiateViewControllerWithIdentifier:(NSString *)identifier;
如果項目中有多個 .storyboard
文件,我們只有先獲取到那個 .storyboard
文件的 Storyboard
實例,才能獲取其中的控制器;
storyboardWithName:bundle:
用來獲取Storyboard
實例,
instantiateViewControllerWithIdentifier:
用來獲取 其中的某個控制器;然后就可以使用代碼對這個控制器進行相應的操作,Push/Present/賦值/調(diào)用方法等等;
雖然可以直接在 Storyboard
進行 Push/Present
的設置,但是有時候也是需要使用代碼來獲取的;當然如果我們在 Storyboard
設置了轉(zhuǎn)場,我們還是可以通過其他的方法來獲取到下一個控制器的;下面會有介紹;
2. UIStoryboardSegue
Segue
的概念對于一個初次使用 Storyboard
人來說比較模糊,其實他就是兩個控制器之間的轉(zhuǎn)場連線:UIStoryboardSegue
提供了與之相關的一些操作方法,獲取 Segue
、觸發(fā) Segue
、獲取與之相關的控制器等;這個類也很簡單,其 API
主要有兩個初始化方法,三個屬性和一個實例方法:
+ (instancetype)segueWithIdentifier:(nullable NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination performHandler:(void (^)(void))performHandler
- (instancetype)initWithIdentifier:(nullable NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination
@property (nullable, nonatomic, copy, readonly) NSString *identifier;
// 從那個控制器過來的
@property (nonatomic, readonly) __kindof UIViewController *sourceViewController;
// 將要出現(xiàn)的控制器
@property (nonatomic, readonly) __kindof UIViewController *destinationViewController;
// 在自定義UIStoryboardSegue的時候,可通過重寫這個方法來定制一些行為
- (void)perform;
其中,我們常用的是那三個屬性:identifier
、sourceViewController
和 destinationViewController
;
最后一個實例方法 perform
,就是上面自定義 UIStoryboardSegue
的子類時必須要實現(xiàn)的方法;
如下圖所示,即是一個Segue
:
在右側(cè)屬性面板的
Storyboard Segue
欄目下:
Identifier
:設置Segue
的唯一標識符
Class
:設置Segue
的關聯(lián)類,一般是UIStoryboardSegue
的子類,除非需要自定義轉(zhuǎn)場,一般不需要設置
Kind
:轉(zhuǎn)場方式,這里選擇的是Push
,可以通過該值選擇其他的方式
當我們通過 Storyboard
進行 Push/Present
的時候,我們可以通過系統(tǒng)方法獲取一個 UIStoryboardSegue
實例,再從中獲取到我們需要的信息;
在我們使用代碼操作 Segue
的時候,一定要確保待操作的 Segue
是已經(jīng)存在的;Segue
的創(chuàng)建是在 Storyboard
中進行連線添加的,他有兩種:第一種是單個控件跳轉(zhuǎn)某個控制器的連線,例如按鈕跳轉(zhuǎn)到下一個控制器,是一對一的關系這種我們不需要使用代碼就可以觸發(fā)相應的事件,在 Storyboard
中創(chuàng)建就能確定關系的;還有一種是控制器之間的連線,可能不止一個連線,跳轉(zhuǎn)到不同控制器,也可能是不同的事件觸發(fā),跳轉(zhuǎn)到同一個控制器,這種是在 Storyboard
中創(chuàng)建 Segue
時,不能確定跳轉(zhuǎn)時機與跳轉(zhuǎn)關系的。
能夠在 Storyboard
中確定跳轉(zhuǎn)關系
這種在 Storyboard
中就可以確定跳轉(zhuǎn)關系,例如通過某個按鈕跳轉(zhuǎn)到下一個控制器,我們可以這樣連線:
連線方法:選中前一個控制器或者其中能夠觸發(fā)事件的控件(例如按鈕),然后按住鍵盤 CTRL(Control)鍵,最后按住鼠標左鍵,拖到需要跳轉(zhuǎn)的控制器中松手;會彈出轉(zhuǎn)場的方式(常用Push/Present等),即可!
不能夠在 Storyboard
中確定跳轉(zhuǎn)關系
上面是通過一個按鈕的事件來轉(zhuǎn)場到下一個場景的連線,按鈕和下一個轉(zhuǎn)場場景是一對一的關系;那如果我們不確定事件觸發(fā)的控件,例如點擊一個
TableView
的cell
來跳轉(zhuǎn)到下一個控制器,這樣我們是不能在添加控件的時候就能確定跳轉(zhuǎn)關系的,像這種一對多的關系應該怎么來添加連線呢, 實現(xiàn)跳轉(zhuǎn)呢?
這里需要兩個步驟,一是添加控制器之間的跳轉(zhuǎn)關系,即添加 Segue,然后在想應的事件中出發(fā)不同的 Segue,來實現(xiàn)不同的跳轉(zhuǎn);第二步使用代碼來觸發(fā)相應的 Segue,實現(xiàn)跳轉(zhuǎn)事件;
- 添加控制器間的
Segue
選中控制器,注意不是任何控件,而是控制器本身,然后按住鍵盤 CTRL(Control)鍵,同時按住鼠標左鍵,拖到需要跳轉(zhuǎn)的控制器中松手;會彈出轉(zhuǎn)場的方式(常用Push/Present等),即可!
然后,選中該 Segue
,在左側(cè)屬性欄設置標識符:
這種方式添加的 Segue
,不會自動觸發(fā),最后需要我們使用下節(jié)介紹的相關 API
來觸發(fā)該Segue
:
[self performSegueWithIdentifier:@"aboutusSegueID" sender:model];
刪除 Segue
刪除一個 Segue
很簡單,選中待刪除的Segue
,然后按鍵盤 Delete
鍵即可;
3. UIViewController 相關 API
UIViewController
是我們使用最多的類之一,其中和 Storyboard
相關的 API
,大概有以下這些:
// 當前控制器所屬的 Storyboard
@property(nullable, nonatomic, readonly, strong) UIStoryboard *storyboard ;
// 使用代碼來進行 Segue 的跳轉(zhuǎn)
// identifier: Segue 標識符
// sender: 攜帶的參數(shù)
- (void)performSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender ;
// Segue 初始化的時候會調(diào)用,重寫這個方法,可以決定當前 Segue 是否能成功跳轉(zhuǎn)
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender ;
// 將要跳轉(zhuǎn)的時候調(diào)用,在這里我們可以獲取到將要跳轉(zhuǎn)的控制器,攜帶一些參數(shù)過去
//sender:對應著 performSegueWithIdentifier 中的sender參數(shù)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender ;
performSegueWithIdentifier
如果我們的點擊事件沒有連線,可以在點擊方法里,使用這個方法來執(zhí)行 Segue
的跳轉(zhuǎn)(連線必須是存在的,但連的不是當前點擊的按鈕);
shouldPerformSegueWithIdentifier
方法是在 Segue
初始化的時候系統(tǒng)自動調(diào)用,可以重寫這個方法,添加一些邏輯判斷,決定當前是否可以跳轉(zhuǎn),返回 YES
可以,返回 NO
不可以;
prepareForSegue
即將跳轉(zhuǎn)的時候調(diào)用,可以重寫這個方法,通過 segue
參數(shù)獲取下一個即將跳轉(zhuǎn)的控制器,進行一些操作,例如傳遞參數(shù)給下一個控制器;
- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender NS_AVAILABLE_IOS(6_0);
// Returns a subset of the receiver's childViewControllers in the order they should be searched for an unwind destination.
// The default implementation first sends itself -childViewControllerContainingSegueSource:, then returns a copy of its childViewControllers array excluding that object. A custom container view controller can override this method to affect the order in which its children are searched, or to modify the result of the default implementation.
// For compatibility, if a view controller overrides the deprecated -viewControllerForUnwindSegueAction:fromViewController:sender: method, but does not override this method, it will receive the deprecated method instead of this method.
// To affect this view controller's eligibility as an unwind destination, override -canPerformUnwindSegueAction:fromViewController:withSender: instead.
- (NSArray<UIViewController *> *)allowedChildViewControllersForUnwindingFromSource:(UIStoryboardUnwindSegueSource *)source NS_AVAILABLE_IOS(9_0);
// Returns the child view controller that contains the provided segue source.
// Custom container view controllers should call this method from their implementation of -allowedChildViewControllersForUnwindingFromSource: to exclude the result from the returned array, as well as to determine the order of the returned array's contents.
// Do not try to re-implement or override this method; it takes special care to handle situations such as unwinding from a modally-presented view controller.
- (nullable UIViewController *)childViewControllerContainingSegueSource:(UIStoryboardUnwindSegueSource *)source NS_AVAILABLE_IOS(9_0);
// Deprecated. Returns a direct child of the receiver that responds YES to -canPerformUnwindSegueAction:fromViewController:withSender:, or self if no children respond YES but the receiver itself does. If this method has been overridden, UIViewController's implementation does not consult child view controllers at all, and skips straight to sending -canPerformUnwindSegueAction:... to self.
// Applications targeting iOS 9 or later should not override this method. Applications can instead override -allowedChildViewControllersForUnwindingFromSource: to guide UIKit’s search for a descendant view controller that returns YES from -canPerformUnwindSegueAction:fromViewController:withSender:.
- (nullable UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(nullable id)sender NS_DEPRECATED_IOS(6_0, 9_0);
// Custom container view controllers should override this method to modify themselves as part of an ongoing unwind segue. The subsequentVC is the parent, child, or presented view controller closest to the receiver in the direction of the segue's destinationViewController. For example, UINavigationController's implementation of this method will pop any necessary view controllers to reveal the subsequentVC.
- (void)unwindForSegue:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC NS_AVAILABLE_IOS(9_0);
// Deprecated. This method is only used for unwind segues whose destination view controller has been returned by an override of the deprecated method -viewControllerForUnwindSegueAction:fromViewController:withSender:. In that case, UIKit will choose a view controller to act as the “executor” of the unwind. If the destination view controller is being modally presented, the destination view controller itself is the executor. Otherwise, the destination view controller’s parent view controller is the executor. If the executor overrides this method, UIKit will ignore the Custom Class specified in Interface Builder and instead call this method on the executor to obtain a segue that can perform the unwind.
// The returned segue object must be able to perform all steps necessary to unwind, including dismissing any intermediate modal presentations or popping any necessary navigation items.
// Applications targeting iOS 9 or later should not override this method. Custom container view controllers should instead override -unwindForSegue:towardsViewController: to modify their local state as part of a UIKit-generated incremental unwind segue.
- (nullable UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(nullable NSString *)identifier NS_DEPRECATED_IOS(6_0, 9_0);
以上都是從前往后的轉(zhuǎn)場,例如 push/present
操作;當然也少不了從后往前的返回操作,例如 pop/dismiss
操作,這就用到了 Unwind Segues
相關的一些方法,具體可參考 使用Unwind Segues
以上就是在使用 Storyboard
時能夠使用到的相關API
。