我們知道創(chuàng)建一個集成UIView的控件的時候,不能像viewcontroller那樣有一個xib,但是又想用xib來布局這個view,這時候就要自定義一個view的xib文件了。
創(chuàng)建一個view的子類customView繼承UIView
緊接著創(chuàng)建一個xib,選擇
下一步的save as名字可以隨便取,建議取成和子類view相同的名字,這里我取得是customView
接下來,把這個view的class改為
這樣,你可以在上邊愉快的拉控件來布局了,但是怎么用呢
在用的時候,可以這樣
customView *customV = [[[NSBundle mainBundle] loadNibNamed:@"customView" owner:self options:nil] firstObject];
此時,在這個xib中,view的大小默認是屏幕的大小,如果你想用熟悉的initWithFrame,可以這樣,在customView.m中,重寫initWithFrame方法
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame: frame];
if (self) {
UIView *vi = [[[NSBundle mainBundle] loadNibNamed:@"customView" owner:self options:nil] firstObject];
vi.frame = frame;
[self addSubview:vi];
}
return self;
}
注意,這里如果你用了拉約束的方法,很多是沒用的(設置水平中心和豎直中有用,也就是視圖中心點跟父視圖一樣),這里你可以把約束拉出來成為一個屬性,在你需要的時候,設置這個屬性就行了。這算是也是一個弊端吧。
接下來,坑來了
如果你在這個xib的view上增加了一個viewOther,在這個viewOther上,你再拉控件,這時候,在viewOther上的控件約束有用了,你想說,這下就可以愉快的用約束了(前提是你的viewOther設置好了約束)。有一個問題,你將控件拉成屬性,是在customView中,你給控件賦值是沒問題的,如果你想設置圓角啊,邊框啊這些屬性,你如果在
- (instancetype)initWithCoder:(NSCoder *)aDecoder
里邊寫,是沒有效果的,這個方法是走了的,但是就是沒效果(原因就是這個方法是初始化costomView的,這個時候,viewOther上的控件,不確定是不是初始化好了)
有些同學可能會在xib中,用kvc的方式來改變,但是邊框顏色是用不來這個的,解決方法很簡單,代碼如下
//customView的初始化方法里
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self layoutIfNeeded];
}
return self;
}
在這里
- (void)layoutSubviews {
//coding what you wang to set
}
這樣,你所有的子view上的控件就會有你想要的效果了。好了,愉快的自定義view吧