SB加载到内存
创建home.storyboard文件、然后通过代码加载到内存中。
//初始化initialViewController (即Storyboard entry point的箭头指向的VC)
UINavigationController *homeVC = [[UIStoryboard storyboardWithName:@"home" bundle:nil] instantiateInitialViewController];
//加载home.storyboard里面指定Identifier的VC、(需要在SB文件中指定该VC的Identifier值)
HomeSearchResultViewController *searchVC = [[UIStoryboard storyboardWithName:@"home" bundle:nil] instantiateViewControllerWithIdentifier:@"HomeSearchResultVC"];
searchVC.keyword = @"sample";
[self.viewController.navigationController pushViewController:searchVC animated:YES];
SB里的VC跳转
VC中间的跳转可以使用segue来实现的。(需要在SB文件里去通过拖拽拉线连接VC之间的Segue、并指定Segue的id,这样才能正确的访问到SB中众多的Segue中的唯一一个)
使用segue转场时,会响应-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
方法。其中segue就是storyBoard转场控制对象,在参数segue中能够获取所要跳转的视图控制器,destinationViewController(目标vc),sourceViewController(源视图vc)。
一、不需要传递参数到目标VC的情况:
[self performSegueWithIdentifier:@"toLoginVC" sender:nil];
二、需要传递参数的情况:
//先调用performSegueWithIdentifier方法,然后自动触发prepareForSegue方法
[self performSegueWithIdentifier:@"toLoginVC" sender:nil];
//在当前的sourceViewController里面添加下面的prepareForSegue方法,在VC跳转前作参数传递的工作
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"toLoginVC"]) {
LoginViewController *loginVC = (LoginViewController *)segue.destinationViewController;
loginVC.account = @"xxxxx";
}
}
上面这种方式有一个痛点,就是跳转要有两处的代码,首尾分离,不便管理。
现在考虑把本来在prepareForSegue里面的代码和performSegueWithIdentifier方法聚合到一起,方便管理。
就有了下面这种方式去实现:
KBSegueSender *sender = [[KBSegueSender alloc] initWithSend:self prepareBlock:^(UIStoryboardSegue *segue) {
BindPhoneViewController *bindPhoneVC = (BindPhoneViewController *)segue.destinationViewController;
bindPhoneVC.wx_user_id = wxId;
}];
[self performSegueWithIdentifier:@"toBindPhoneVC" sender:sender];
KBSegueSender是定义的Model,用来包裹block的属性。
#import <Foundation/Foundation.h>
typedef void(^PrepareBlock)(UIStoryboardSegue * segue) ;
@interface KBSegueSender : NSObject
@property(assign)id sender;
@property(assign) PrepareBlock prepareBlock;
- (id)initWithSend:(id)sender prepareBlock:(PrepareBlock) block;
@end
#import "KBSegueSender.h"
@implementation KBSegueSender
- (id)initWithSend:(id)sender prepareBlock:(PrepareBlock) block {
self = [super init];
if (self) {
self.sender = sender;
self.prepareBlock = block;
}
return self;
}
@end
//通过Block将参数传递代码聚合起来,然后通过创建Category来在prepareForSegue去执行block,完成值得传递。
#import "UIViewController+KBAdditional.h"
#import "KBSegueSender.h"
@implementation UIViewController (KBAdditional)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([sender isKindOfClass:[KBSegueSender class]]) {
KBSegueSender *segueSender = (KBSegueSender*)sender;
segueSender.prepareBlock(segue);
}
}
@end