前言: 去年开始使用xib进行界面开发,相比代码,效率更高,大大节省了时间. 但是在使用时,碰到一个问题一直很让我疑惑, 虽然我知道应该在什么时候用哪种方式, 但是内部的原因还不是很懂.
我们在使用xib创建自定义视图时,有两种方式:
如下图标记 1代表第一种方式,2代表第二种方式
我并不知道这两种创建方式的根本区别,表面区别是创建之后里面一个有view,一个没有需要手动添加. 但是这两种在使用时却不同.
使用2方式创建xib,内部是空的, 需要手动添加一个view, 点击view.在右部将class命名为此xib的名字. 控件,布局之类的略过,这篇文章的重点不是他们.
然后在viewcontroller中调用这个view(以下称xib2):
CustomView *view = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil].firstObject
你也可以将上一句代码进行封装:
//自定义一个快速初始化方法
+ (instancetype)customInit{
// 封装Xib的加载过程
return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil].firstObject;
}
这样调用的时更加方便,所以实际使用时是这样:
CustomBarItem *customView = [CustomBarItem customInit];
[self.view addSubviews:customView];
这样你用xib自定义的视图就被添加到view,可以进行显示.
可以如果遇到另外一种情景: 你在viewcontrollerxib文件中添加了一个view,然后将这个view 的class改为xib2的名字, 然后这样在viewController显示. 然后就会crash,是不是很惊喜, 崩溃信息不记得了,可以等以后再补充.
所以用2方式创建的xib视图,只适合创建一个对象,然后被添加到视图上. 若想在另一个xib文件中使用此xib文件,会出错.
那么这就需要说道第一种形式了: 创建之后的xib自带一个view, 点击 File's Owner
,更改class ;
这里和2方式的第一个区别也是很重要的在于: 1方式更改的是File's Owner
的class, 2方式更改的是view的class.
然后:
在.m文件中实现加载contentView:
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[[NSBundle mainBundle] loadNibNamed:@"CustomIndexNavBarView" owner:self options:nil];
self.contentView.frame = self.bounds;
[self addSubview:self.contentView];
}
return self;
}
这样操作之后, 就可以在viewcontroller中添加一个view,将view的class更改成xib自定义的view名字, 这样既可以将自定义的view显示, 即 在xib中使用另一个xib.
在使用xib开发的过程中,因为业务的缘故,一直使用2方式进行创建的; 有次要实现在xib中使用xib(其实就是在viewcontroller的xib文件中加载一个自定义的xib视图), 原有的方式无法实现. 我在搜索资料完之后,找到第一种方式,实现了功能.
虽然现在知道了两种方式的区别, 以及该在什么时候使用哪种方式也是很清晰明了, 但是这两种方式的根本区别, 我还是不知道. 以后知道了,会进行补充, 若是哪位知道, 请不吝赐教.
文章写的比较匆忙, 只是想把遇到在这个问题记录一下, 有错误的地方,请指出.