[iOS] Storyboard (1) -- 入门:API 篇

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

UIStoryboardAPI 很简单,主要有一个初始化方法,和两个实例方法:

//  通过 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;

其中,我们常用的是那三个属性:identifiersourceViewControllerdestinationViewController

最后一个实例方法 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 中确定跳转关系

上面是通过一个按钮的事件来转场到下一个场景的连线,按钮和下一个转场场景是一对一的关系;那如果我们不确定事件触发的控件,例如点击一个 TableViewcell 来跳转到下一个控制器,这样我们是不能在添加控件的时候就能确定跳转关系的,像这种一对多的关系应该怎么来添加连线呢, 实现跳转呢?

这里需要两个步骤,一是添加控制器之间的跳转关系,即添加 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342