加载控制器的View一共有六种方式,本篇介绍的是其中的一种---加载与控制器同名去掉Controller后缀的View。
假设有一个视图控制器叫做MGSimpleViewController,如果通过以下方式创建,那么会加载什么View作为视图控制器的根View呢?
MGSimpleViewController *vc = [[MGSimpleViewController alloc] init];
通过这行代码并不能确切知道创建出来的View是什么样子的,具体还得看以下几个点:
- 控制器实现文件是否覆盖
-(void)loadView并且在方法中设置了self.view = xxView,如果是,那么视图控制器的View就是xxView,如果否,那么进入第2点。 - 工程目录下是否存在一个叫做
MGSimpleView.xib的文件,如果是,那么这个MGSimpleView.xib中指定的View就是视图控制器的View,如果否,那么进入第3点。 - 工程目录下是否存在一个叫做
MGSimpleViewController.xib的文件,如果是,那么这个MGSimpleViewController.xib中指定的View就是视图控制器的View,如果否,那么进入第4点。 - 视图控制器自己创建一个空白的
View对象,并且将其作为根视图,可以通过self.view进行访问。
除了上面4种还有另外2种方法,一种是通过加载SB文件,另一种是加载其它名字的Xib文件,创建一个视图控制器的根View一共就这六种方法(还有一种说法---七种,把-(void)loadView中不同的加载方式当做不同的创建方法,比如通过Xib和通过SB,但这里我就且当作一种)。
说完总的创建方法之后,现在只拎上面的第2种方法介绍一下,因为这种创建方式其实有不少需要注意的地方。
- 首先创建目标控制器

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

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

4.重点来了

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

这步操作的意义是,给
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,所以还差最后一个步奏。

通过上面的操作,现在编译器就知道去找MGSimpleView.xib中view outlet关联的那个UIView控件作为视图控制器的根view。MGSimpleViewControll.m可以这样写:
#import "MGSimpleViewController.h"
#import "MGSimpleView.h"
@interface MGSimpleViewController ()<MGSimpleViewDelegate,MGSimpleViewDataSource>
@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之间的实现就是这种,代码风格也是一致。