當(dāng)我們需要自定義一個(gè)View控件時(shí)沈堡,會(huì)有 initWithFrame静陈、initWithCoder、awakeFromNib 這三個(gè)系統(tǒng)方法诞丽,關(guān)于這三個(gè)方法何時(shí)調(diào)用鲸拥,如何調(diào)用,有時(shí)候可能很多人會(huì)弄混淆僧免。
下面我會(huì)就理論結(jié)合代碼舉例來(lái)說(shuō)明一下:
1刑赶、initWithFrame
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSLog(@"initWithFrame");
[self initViews];
}
return self;
}
這個(gè)方法是當(dāng)控件不是從xib、storyboard中創(chuàng)建時(shí)懂衩,會(huì)調(diào)用這個(gè)方法撞叨,比如:
XibShow *xib = [[XibShow alloc] initWithFrame:CGRectMake(0, 330, KScreenWidth, 100)];
[self.view addSubview:xib];
這里我直接用 [XibShow alloc] initWithFrame 來(lái)創(chuàng)建控件金踪,所以,這里自定義控件內(nèi)谒所,只會(huì)走 initWithFrame 方法热康,其余兩個(gè)不會(huì)走。
2劣领、initWithCoder
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
NSLog(@"initWithCoder");
[self initViews];
}
return self;
}
當(dāng)控件是從xib姐军、storyboard中創(chuàng)建時(shí),就會(huì)調(diào)用這個(gè)方法尖淘。
概括的理解就是:你的view或cell在xib或storyboard上有體現(xiàn)奕锌,比如直接用xib創(chuàng)建的,或是拉控件關(guān)聯(lián)已有類等村生。
而且惊暴,即使我們自定義的view是純代碼,沒有xib趁桃,但我們?cè)趘c的xib里引用了辽话,效果是一樣的。
比如卫病,這兩種方式創(chuàng)建的自定義view油啤,只要我們有在xib或storyboard里引用過(guò),就都會(huì)執(zhí)行initWithCoder和awakeFromNib
3蟀苛、awakeFromNib
-(void)awakeFromNib{
NSLog(@"awakeFromNib");
[super awakeFromNib];
[self initViews];
}
這個(gè)方法在initWithCoder:方法后調(diào)用 益咬,順序是:initWithCoder -> awakeFromNib (下面會(huì)有代碼截圖)
- 可以這么來(lái)理解:
一開始經(jīng)過(guò)initWithCoder創(chuàng)建出來(lái)的控件是死的,然后通過(guò)awakeFromNib來(lái)喚醒帜平,所以這會(huì)有一個(gè)先后的調(diào)用順序幽告。
下面會(huì)有一個(gè)具體的示例:
1、創(chuàng)建一個(gè)vc裆甩,在storyboard上關(guān)聯(lián)界面冗锁,在界面上新增一個(gè)view,關(guān)聯(lián)我們的自定義view:XibShow淑掌。
2蒿讥、在vc里,再額外用代碼新增一個(gè)自定義view控件抛腕,add到另一個(gè)位置。
這樣媒殉,運(yùn)行出來(lái)的結(jié)果如下:
其中:打印順序如上圖所示担敌。
可以發(fā)現(xiàn):
1、在viewDidLoad之前廷蓉,由于是storyboard上創(chuàng)建的類全封,會(huì)先執(zhí)行好马昙,且會(huì)順序走 initWithCoder、awakeFromNib兩個(gè)方法
2刹悴、到viewDidLoad之后行楞,執(zhí)行到用代碼創(chuàng)建的view,只會(huì)走 initWithFrame 方法
PS:這里還有個(gè)小細(xì)節(jié):我在storyboard上托控件創(chuàng)建的類土匀,即使我給了背景色子房,但執(zhí)行出來(lái),還是以自定義view本身的背景色為準(zhǔn)就轧。
(可以看上圖证杭,開始設(shè)的灰色,但運(yùn)行出來(lái)還是紅色)
最后總結(jié):
1妒御、initWithFrame只適用純代碼創(chuàng)建時(shí)調(diào)用解愤,不涉及xib或storyboard。
2乎莉、initWithCoder送讲、awakeFromNib是從xib、storyboard中創(chuàng)建時(shí)會(huì)調(diào)用惋啃。
3哼鬓、所以一般來(lái)說(shuō),為了安全起見肥橙,初始化控件的代碼我們寫在一個(gè)方法里面(類似我上面的initViews方法)魄宏,然后我們分別在initWithFrame和initWithCoder中都調(diào)用一下,這樣就保證了無(wú)論你是通過(guò)什么方式創(chuàng)建的控件存筏,代碼都能起到作用宠互。