initWithFrame和layoutSubviews的用法

本文详细解释了iOS开发中initWithFrame方法的作用及其应用场景。包括其在视图初始化中的作用、与InterfaceBuilder的关系,以及如何正确地在UIView子类中重写此方法。

一开始看别人的代码,看到这两个词的时候,瞬间感到懵了,两个似乎都是初始化子控件,到底两个有什么区别呢?



1. initWithFrame方法是什么?


initWithFrame方法用来初始化并返回一个新的视图对象,根据指定的CGRect(尺寸)。
当然,其他UI对象,也有initWithFrame方法,但是,我们以UIView为例,来搞清楚initWithFrame方法。


2.什么时候用initWithFrame方法?
简单的说,我们用编程方式申明,创建UIView对象时,使用initWithFrame方法。
在此,我们必须搞清楚,两种方式来进行初始化UIView。
1.使用 Interface Builder 方式。
这种方式,就是使用nib文件。通常我们说的“拖控件” 的方式。


实际编程中,我们如果用Interface Builder 方式创建了UIView对象。(也就是,用拖控件的方式)
那么,initWithFrame方法方法是不会被调用的。因为nib文件已经知道如何初始化该View。(因为,我们在拖该view的时候,就定义好了长、宽、背景等属性)。
这时候,会调用initWithCoder方法,我们可以用initWithCoder方法来重新定义我们在nib中已经设置的各项属性。


2.使用编程方式。
就是我们声明一个UIView的子类,进行“手工”编写代码的方式。


实际编程中,我们使用编程方式下,来创建一个UIView或者创建UIView的子类。这时候,将调用initWithFrame方法,来实例化UIView。
特别注意,如果在子类中重载initWithFrame方法,必须先调用父类的initWithFrame方法。在对自定义的UIView子类进行初始化操作。
比如:


- (id)initWithFrame:(CGRect)frame{


    self = [super initWithFrame:frame];// 先调用父类的initWithFrame方法


    if (self) {


        


        // 再自定义该类(UIView子类)的初始化操作。


        _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];


        [_scrollView setFrame:CGRectMake(0, 0, 320, 480)];


        _scrollView.contentSize = CGSizeMake(320*3, 480);


        


        [self addSubview:_scrollView];


    }


    return self;


}


个人总结就是程序会先执行initWIthFrame方法,把要添加的子控件添加上去,然后在计算子控件的Frame,即执行layOutSubViews方法

每个ios开发者对loadViewviewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是类似的initWithNibName/awakeFromNib/initWithCoder放在一起还是非常容易让人混淆的. 昨天看了下苹果官方的相关文档以及几篇相关内容的网页(一 二 三),其实这个内容以前也看过,似乎也搞清楚了,可还是忘了.好急性不如烂笔头,这次一定要好好记下来. 大前提是UIViewController有一个UIView.同时,需要厘清两个概念,创建一个类实例化一个类.在XCode中创建一个类实例化一个类很容易区分,但是在IB(Interface Builder)中有时候就会迷糊.其实也很好区分,孤零零地创建了一个nib文件,没有其他可被实例化的类有直接或间接关系的时候,这个类或这些类(一个nib文件俺也可能包含多个类)是没有机会被实例化的,所以这种情况只是通过ib创建了一个类,而没有实例化.真正的实例化还需要通过在Xcode用代码来读取这个nib文件.知道这两这的区别后这些方法也就容易辨认多了,viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法. loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它. initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的. awakeFromNib这个方法是一个类在IB中被实例化是被调用的.看了帖子发现大家都推荐使用viewDidLoad而不要使用awakeFromNib,应为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次.实际测试中发现,当一个类的awakeFromNib被调用的时候,那么这个类的viewDidLoad就不会被调用了,这个感觉很奇怪. initWithCoder是一个类在IB中创建但在xocdde中被实例化时被调用的.比如,通过IB创建一个controller的nib文件,然后在xocde中通过initWithNibName来实例化这个controller,那么这个controller的initWithCoder会被调用. 如果你的对象是UIViewControler的子类,那么你必须调用- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil;方法去调用NIB文件初始化自身,即使那没有使用nib文件也会调用这个函数(默认情况下init方法已经为你的做这件事情了),如果你调用这个方法,并传递的两个参数为空(nil),然后类会调用-loadView去读取一个名字你的UIViewController名字相同的nib文件,来初始化自身。如果没有这样的nib文件,你必须调用-setView:来设置一个self.view。或者重载-loadView 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值