initWithCoder: 与initWithFrame:的区
2018-07-23 本文已影响0人
Mr_Coder
有时候,知道initWithFrame方法如何用,但是没有弄明白initWithCoder方法到底是什么?
1.使用纯代码编程创建一个UIView子类,此时调用initWithFrame方法来实例化UIView。
自定义view的基本步骤
1>.重写 - (id)initWithFrame方法,在此方法中创建并添加子控件。
2>.提供一个便利的构造方法,通常为类方法,快速创建一个实例对象
3>.重写 - (void)layoutSubviews方法,在此方法中设置子控件的frame,
一定要调用[super layoutSubviews]
4>.设置模型属性,在set方法中,给对应的子控件赋值。
创建UIVIew子类
#import "FrameView.h"
@implementation FrameView
-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
//1.初始化控件,coding...
self.backgroundColor = [UIColor redColor];
}
return self;
}
// 2.重写layoutSubviews,给自己内部子控件设置frame
- (void)layoutSubviews {
[super layoutSubviews];
//coding...
}
// 3.调用模型的set方法,给书的子控件赋值,
- (void)setDic:(NSDictionary *)dic {
_dic = dic;
//coding...
}
@end
在使用地方实例化UIView
FrameView *frameView = [[FrameView alloc] initWithFrame:self.view.frame];
[self.view addSubview:frameView];
注:
1>.一般来说我们的自定义类继承自UIView,首先在initWithFrame:方法中将需要的子控件加入view中。
注意:这里只是加入到view中,并没有设置各个子控件的尺寸。并且是在initWithFrame方法中而不是init方法
2>.initWithFrame:中添加子控件。
layoutSubviews中设置子控件frame。
对外设置数据接口,重写setter方法给子控件设置显示数据。(model)
在view controller里面使用init/initWithFrame:方法创建自定义类,并且给自定义类的frame赋值。
对自定义类对外暴露的数据接口进行赋值即可。
2.使用Interface Building(也就是拖控件)创建自定义View
xib关联自定义view的步骤:
1>. 创建一个自定义的view:
创建UIView时候 Also create XIB file 的选项是不能被勾选的,与自定义cell不同
2>.创建一个同名的xib: User Interface -> View
3>.设置xib的File`s Owner的Custome Class属性为自定义的view:
4>.然后在自定义的view里面重写你需要初始化的方法:
NibView *nibView = [[[NSBundle mainBundle] loadNibNamed:@"NibView" owner:nil options:nil] objectAtIndex:0];
创建UIView子类:
@implementation NibView
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
//coding...
self.backgroundColor = [UIColor yellowColor];
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
@end
在使用的地方实例化
NibView *nibView = [[[NSBundle mainBundle] loadNibNamed:@"NibView" owner:nil options:nil] objectAtIndex:0];[self.view addSubview:nibView];
注:
系统的调用流程: initWithCoder —> awakeFromNib —> layoutSubviews
编程中如果使用了XIB方式创建UIView对象,那么initWithFrame:方法是不会加载Nib上的内容的,因为nib文件已经知道如何初始化该view(拖控件的时候就已经定义好了尺寸、属性等);此时会调用initWithCoder方法,我们可以用initWithCoder方法来重新定义我们在nib中已经设置的各项属性
1>.加载XIB后,系统会自动调用 - (id)initWithCoder:(NSCoder*)aDecoder 方法来初始化控件,其中aDecoder是一个解析器,对XIB进行解析;不能在这个方法中给XIB里自定义view的子控件进行初始化,因为initWithCoder:方法是‘处于正在初始化’,有些细节还没有初始化完毕,可能还没给子控件进行连线等,但是可以在initWithCoder:方法里对自定义View进行初始化,但不能设置View的Frame值,且一般XIB的初始化操作在awakeFromNib里进行
2>.如果还需要用代码添加子控件,可以通过重写initWithCoder:方法,在方法里面用代码添加子控件和初始化,添加的子控件的Frame值也要在layoutSubviews方法里设置。
3>.当控件从XIB中创建完毕后会调用awakeFromNib方法,XIB的所有的初始化操作应该在这个方法里进行,但不能在这个方法中对子控件设置Frame的值
4>.如果需要重新设置子控件的Frame值,应该在layoutSubviews方法里进行设置,因为父控件的Frame只要改变就就会调用该方法
5>.用XIB封装自定义的View,控件从XIB中创建的过程不会调用init方法和initWithFrame:方法