initWithCoder: 与initWithFrame:的区别

有时候,知道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:方法

你可能感兴趣的:(initWithCoder: 与initWithFrame:的区别)