在博客 iOS AutoLayout: 关联 Xib 和 UIViewController
讨论了 UIViewController 如何和一个 xib 关联并且展现出来.
在那篇博客中, 最后说到使用下面这种方式可以加载 ViewController
-(instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil
今天和大家一起聊聊.
新建一个 iOS 工程, single view 即可.
创建一个 ViewController, 即 MainPage
然后再创建一个名称为 MainPage 的 xib 文件.
工程文件大概这个样子:
按照博客 iOS AutoLayout: 关联 Xib 和 UIViewController
里面那样设置 File owner 和 View 的关联.
设置后如下图
xib 效果图很简单
MainPage.m
#import "MainPage.h"
@interface MainPage ()
@property (strong, nonatomic) IBOutlet UIButton *byeBtn;
@property (strong, nonatomic) IBOutlet UILabel *xx;
@end
@implementation MainPage
- (instancetype)init
{
NSLog(@"MainPage | init...");
self = [super init];
if (self) {
}
return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
NSLog(@"MainPage | initWithNibName...");
if (self == [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.xx.text = @"start...";
}
- (IBAction)onClickByeBtn:(id)sender
{
[self dismissViewControllerAnimated:YES completion:^{
}];
}
@end
在根控制器(ViewController)里面打开 MainPage
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self performSelector:@selector(goPage) withObject:nil afterDelay:1.f];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)goPage
{
MainPage *page = [[MainPage alloc] initWithNibName:@"MainPage" bundle:nil];
[self presentViewController:page animated:YES completion:^{
}];
}
@end
运行, 既可以看到效果.
没有任何异常的 crash.
下面, 我们修改一下打开 MainPage 的方式
- (void)goPage
{
//MainPage *page = [[MainPage alloc] initWithNibName:@"MainPage" bundle:nil];
MainPage *page = [[MainPage alloc] init];
[self presentViewController:page animated:YES completion:^{
}];
}
一样可以展现视图内容.
看一下控制台日志
MainPage | init…
MainPage | initWithNibName…
可以看出, init 最终调用了 initWithNibName 方法.
这个时候, 大家可以猜想, UIViewController 会默认调用initWithNibName方法, 换句话说, 或优先考虑 xib.
并且加载 xib 是使用默认的类名称来加载的.
于是乎…
你把 MainPage.xib 这个文件修改一下名称, 使用第一种加载方式会 crash, 因为找不到对应的 xib 文件.
除非你指定修改后的 xib 文件名.
使用第二种也是展现一个空视图.
另外, 如果你想省去单独设置 xib 的 File Owner 以及和 View 直接的关系, 可以在创建 ViewController 的时候, 选择Also create XIB file这个选项, 会自动帮你设置.
推荐大家阅读
- 浅论ViewController的加载
- 关于 initWithNibName 和 loadNibNamed 的区别和联系