加载控制器同名去掉Controller后缀的View

加载控制器的View一共有六种方式,本篇介绍的是其中的一种---加载与控制器同名去掉Controller后缀的View。

假设有一个视图控制器叫做MGSimpleViewController,如果通过以下方式创建,那么会加载什么View作为视图控制器的根View呢?

MGSimpleViewController *vc = [[MGSimpleViewController alloc] init];

通过这行代码并不能确切知道创建出来的View是什么样子的,具体还得看以下几个点:

  1. 控制器实现文件是否覆盖-(void)loadView并且在方法中设置了self.view = xxView,如果是,那么视图控制器的View就是xxView,如果否,那么进入第2点。
  2. 工程目录下是否存在一个叫做MGSimpleView.xib的文件,如果是,那么这个MGSimpleView.xib指定的View就是视图控制器的View,如果否,那么进入第3点。
  3. 工程目录下是否存在一个叫做MGSimpleViewController.xib的文件,如果是,那么这个MGSimpleViewController.xib指定的View就是视图控制器的View,如果否,那么进入第4点。
  4. 视图控制器自己创建一个空白的View对象,并且将其作为根视图,可以通过self.view进行访问。

除了上面4种还有另外2种方法,一种是通过加载SB文件,另一种是加载其它名字的Xib文件,创建一个视图控制器的根View一共就这六种方法(还有一种说法---七种,把-(void)loadView中不同的加载方式当做不同的创建方法,比如通过Xib和通过SB,但这里我就且当作一种)。


说完总的创建方法之后,现在只拎上面的第2种方法介绍一下,因为这种创建方式其实有不少需要注意的地方。

  1. 首先创建目标控制器
Snip20170227_122.png

2.创建同名去掉Controller,继承自UIView的头文件和实现文件

加载控制器同名去掉Controller后缀的View_第1张图片
Snip20170227_123.png

3.由于父类是UIView,所以无法在创建的时候顺便创建XIB,所以我们手动创建同名的XIB

加载控制器同名去掉Controller后缀的View_第2张图片
Snip20170227_124.png
4.重点来了

加载控制器同名去掉Controller后缀的View_第3张图片
Snip20170227_127.png

上面的是将 MGSimpleView.h\.mMGSimpleView.xib的文件关联起来,这里应该都理解,进入下一步

加载控制器同名去掉Controller后缀的View_第4张图片
Snip20170227_126.png

这步操作的意义是,给 MGSimpleView.xib这个文件设置它的拥有者(视图控制器)所以图中第3点填的是视图控制器,而不是视图!通过上面的两张图片的操作,现在编译器知道在加载 MGSimpleViewController的时候去 MGSimpleView.xib中寻找合适的 View作为控制器的 根View,并且编译器也知道了 MGSimpleView.xib关联的是 MGSimpleView.h\.m文件。
但是一个 XIB文件中可以存在多个一级视图,所以我们在通过 UINIB加载 XIB文件的时候是这样写的:

NSArray *views = [[UINib nibWithNibName:@"MGXxView" bundle:nil] instantiateWithOwner:nil options:nil];

MGXxView *xxView = views[index];

所以到现在为止,编译器还不知道要MGSimpleView.xib中的哪个View,如果这个时候运行的话,会出现下面的错误:

-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "MGSimpleView" nib but the view outlet was not set

这段反馈信息的意思是我们没有设置MGSimpleView中的view outlet的关联对象,因为没有这个对象,编译器就不知道要加载MGSimpleView.xib中的哪一个View作为MGSimpleViewController根view,所以还差最后一个步奏。

加载控制器同名去掉Controller后缀的View_第5张图片
Snip20170227_128.png

通过上面的操作,现在编译器就知道去找MGSimpleView.xibview outlet关联的那个UIView控件作为视图控制器的根viewMGSimpleViewControll.m可以这样写:

#import "MGSimpleViewController.h"
#import "MGSimpleView.h"

@interface MGSimpleViewController ()
@property(nonatomic,weak)MGSimpleView *simpleView;
@end

@implementation MGSimpleViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.simpleView = (MGSimpleView *)self.view;
    self.simpleView.delegate = self;
    self.simpleView.dataSource = self;
}

#pragma mark - MGSimpleViewDataSource
-(NSDictionary *)requestParamsWithSimpleView:(MGSimpleView *)simpleView{
    return @{@"username" : @"Mango"};
}

#pragma mark - MGSimpleViewDelegate
-(void)simpleView:(MGSimpleView *)simpleView didClickRegisterBtn:(UIButton *)registerBtn{
    NSLog:(@"register");
}

这种风格应该不会陌生,因为UITableViewController和UITableView之间的实现就是这种,代码风格也是一致。

你可能感兴趣的:(加载控制器同名去掉Controller后缀的View)