通过 XIB 加载 UIView

在项目中有些 view 需要独立做成一个组件,供多个 VC 使用,而且本人项目中习惯使用 XIB,所以这个 view 的组件也希望使用 XIB 来实现。但是当我们创建 UIView 的时候默认是不包含 XIB 文件的,这就需要再创建一个同名的 XIB 文件。但是如何把 XIB 和 UIview 关联起来呢。

通常我们通过代码加载 XIB 的方法是:

+(id)viewFromNibNamed:(NSString*)nibName owner:(id)owner{
NSArray* nibView = [[NSBundle mainBundle] loadNibNamed:nibName owner:owner options:nil];
return [nibView firstObject];
}

注意到上面有一个 owner 属相,这个属性就是表明这个 view 文件的所有者,通常对应一个 VC。

单纯的创建 view 类和同名的 XIB 是没有效果的,接下来要做的就是把 XIB 和对应的 view 类关联起来

关联有两种方式,假设自定义的的UIView子类为TestView,三个文件分别为:TestView.h,TestView.m,TestView.xib

XIB 中的 UIView 控件与类关联

通过XIB加载UIView-1

这种方式就是设置 XIB 中 view 的 custom class 为TestView。

使用方式为

NSArray* nibView = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:nil options:nil];
TestView *testView = [nibView firstObject];
[self.view addSubview:testView];

这种方式会通过 initWithCoder: 方法来从 XIB 文件初始化该 view。使用的时候我们可以通过 awakeFromNib 方法来做进一步处理。

通过这种方式需要注意的是在initWithCoder:方法中,并没有建立 XIB 和 TestView 的 IBOutlet 连接,所以在这里通过代码引用 XIB 中的控件是引用不到的,而当awakeFromNib执行的时候,各种 IBOutlet 都连接好了。所以如果有子控件的初始化工作,最好放在awakeFromNib里面。

通过 File’s owner 来关联

通过XIB加载UIView-2

这种方式是设置 XIB 中的 File’s owner 为TestView。

这种方式创建 view 需要手动来初始化

- (instancetype)initFromNibWithFrame:(CGRect)frame owner:(id)owner{
owner = owner ?: self;
UIView *nibView = [UIView viewFromNibNamed:NSStringFromClass([self class]) owner:owner];
if (!nibView) return nil;
nibView.frame = frame;
self = [super initWithFrame:nibView.frame];
[self addSubview:nibView];
[self nib_viewDidLoad];

return self;
}

初始化可以在自定义的nib_viewDidLoad里面进行,这个时候 XIB 和 TestView 的 IBOutlet 连接也已经建立好了

由于XIB没有设置 view 的 custom class 所以并不会执行initWithCoder:awakeFromNib方法。

缺点

上面两种方式都可以实现通过代码加载 XIB 的目的。

但是有一种情况就是我们的 viewController 也使用 XIB 来布局的,这个时候如果我们拖拽一个 view 在 VC 的 XIB 中,然后设置这个 View 的 custom class 为 TestView 时,上面的方法就无效了。因为虽然同样是 TestView ,但是加载布局文件不同,这里所加载的布局文件是 VC 所在 XIB 的布局文件。

另外,XIB 中的 file’s owner 其实也就类似是传统 MVC 中的 controller 的角色,因此其最好是 UIVIew,NSObject,UIViewController 这样的类。

参考

如何设计一个 iOS 控件?(iOS 控件完全解析)
-loadNibNamed:owner:options:的深入研究
ios 开发file’s owner以及outlet与连线的理解
对xib/nib, file’s owner, first responder的理解