美文网首页iOS
initWithCoder: 与initWithFrame:的区

initWithCoder: 与initWithFrame:的区

作者: Mr_Coder | 来源:发表于2018-07-23 13:29 被阅读0次

    有时候,知道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:的区

        本文链接:https://www.haomeiwen.com/subject/ovndmftx.html