iOS AutoLayout: 从 XIB 中加载 UIViewController

在博客 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_第1张图片

按照博客 iOS AutoLayout: 关联 Xib 和 UIViewController
里面那样设置 File owner 和 View 的关联.

设置后如下图

iOS AutoLayout: 从 XIB 中加载 UIViewController_第2张图片

3

xib 效果图很简单

iOS AutoLayout: 从 XIB 中加载 UIViewController_第3张图片

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这个选项, 会自动帮你设置.

推荐大家阅读

  1. 浅论ViewController的加载
  2. 关于 initWithNibName 和 loadNibNamed 的区别和联系

你可能感兴趣的:(iOS)