Storyboard 系列文章
[iOS] Storyboard (1) -- 入门:API 篇
[iOS] Storyboard (2) --入门:约束篇
[iOS] Storyboard (3) -- 使用:常用Tips
[iOS] Storyboard (4) -- 实践:问题总结
[iOS] Storyboard (4) -- 实践:UIScrollView
[iOS] Storyboard (4) -- 实践:UICollectionView
在 iOS
中有两种可以实现的可视化编程的方法,一种是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/赋值/调用方法等等;
虽然可以直接在 Storyboard
进行 Push/Present
的设置,但是有时候也是需要使用代码来获取的;当然如果我们在 Storyboard
设置了转场,我们还是可以通过其他的方法来获取到下一个控制器的;下面会有介绍;
2. UIStoryboardSegue
Segue
的概念对于一个初次使用 Storyboard
人来说比较模糊,其实他就是两个控制器之间的转场连线:UIStoryboardSegue
提供了与之相关的一些操作方法,获取 Segue
、触发 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;
// 将要出现的控制器
@property (nonatomic, readonly) __kindof UIViewController *destinationViewController;
// 在自定义UIStoryboardSegue的时候,可通过重写这个方法来定制一些行为
- (void)perform;
其中,我们常用的是那三个属性:identifier
、sourceViewController
和 destinationViewController
;
最后一个实例方法 perform
,就是上面自定义 UIStoryboardSegue
的子类时必须要实现的方法;
如下图所示,即是一个Segue
:
在右侧属性面板的
Storyboard Segue
栏目下:
Identifier
:设置Segue
的唯一标识符
Class
:设置Segue
的关联类,一般是UIStoryboardSegue
的子类,除非需要自定义转场,一般不需要设置
Kind
:转场方式,这里选择的是Push
,可以通过该值选择其他的方式
当我们通过 Storyboard
进行 Push/Present
的时候,我们可以通过系统方法获取一个 UIStoryboardSegue
实例,再从中获取到我们需要的信息;
在我们使用代码操作 Segue
的时候,一定要确保待操作的 Segue
是已经存在的;Segue
的创建是在 Storyboard
中进行连线添加的,他有两种:第一种是单个控件跳转某个控制器的连线,例如按钮跳转到下一个控制器,是一对一的关系这种我们不需要使用代码就可以触发相应的事件,在 Storyboard
中创建就能确定关系的;还有一种是控制器之间的连线,可能不止一个连线,跳转到不同控制器,也可能是不同的事件触发,跳转到同一个控制器,这种是在 Storyboard
中创建 Segue
时,不能确定跳转时机与跳转关系的。
能够在 Storyboard
中确定跳转关系
这种在 Storyboard
中就可以确定跳转关系,例如通过某个按钮跳转到下一个控制器,我们可以这样连线:
连线方法:选中前一个控制器或者其中能够触发事件的控件(例如按钮),然后按住键盘 CTRL(Control)键,最后按住鼠标左键,拖到需要跳转的控制器中松手;会弹出转场的方式(常用Push/Present等),即可!
不能够在 Storyboard
中确定跳转关系
上面是通过一个按钮的事件来转场到下一个场景的连线,按钮和下一个转场场景是一对一的关系;那如果我们不确定事件触发的控件,例如点击一个
TableView
的cell
来跳转到下一个控制器,这样我们是不能在添加控件的时候就能确定跳转关系的,像这种一对多的关系应该怎么来添加连线呢, 实现跳转呢?
这里需要两个步骤,一是添加控制器之间的跳转关系,即添加 Segue,然后在想应的事件中出发不同的 Segue,来实现不同的跳转;第二步使用代码来触发相应的 Segue,实现跳转事件;
- 添加控制器间的
Segue
选中控制器,注意不是任何控件,而是控制器本身,然后按住键盘 CTRL(Control)键,同时按住鼠标左键,拖到需要跳转的控制器中松手;会弹出转场的方式(常用Push/Present等),即可!
然后,选中该 Segue
,在左侧属性栏设置标识符:
这种方式添加的 Segue
,不会自动触发,最后需要我们使用下节介绍的相关 API
来触发该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 的跳转
// identifier: Segue 标识符
// sender: 携带的参数
- (void)performSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender ;
// Segue 初始化的时候会调用,重写这个方法,可以决定当前 Segue 是否能成功跳转
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender ;
// 将要跳转的时候调用,在这里我们可以获取到将要跳转的控制器,携带一些参数过去
//sender:对应着 performSegueWithIdentifier 中的sender参数
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender ;
performSegueWithIdentifier
如果我们的点击事件没有连线,可以在点击方法里,使用这个方法来执行 Segue
的跳转(连线必须是存在的,但连的不是当前点击的按钮);
shouldPerformSegueWithIdentifier
方法是在 Segue
初始化的时候系统自动调用,可以重写这个方法,添加一些逻辑判断,决定当前是否可以跳转,返回 YES
可以,返回 NO
不可以;
prepareForSegue
即将跳转的时候调用,可以重写这个方法,通过 segue
参数获取下一个即将跳转的控制器,进行一些操作,例如传递参数给下一个控制器;
- (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);
以上都是从前往后的转场,例如 push/present
操作;当然也少不了从后往前的返回操作,例如 pop/dismiss
操作,这就用到了 Unwind Segues
相关的一些方法,具体可参考 使用Unwind Segues
以上就是在使用 Storyboard
时能够使用到的相关API
。