版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.04.11 |
前言
iOS中的視圖加載可以有兩種方式热鞍,一種是通過xib加載闷尿,另外一種就是通過純代碼加載塑径。它們各有優(yōu)點(diǎn)和好處,xib比較直觀簡(jiǎn)單填具,代碼比較靈活但是看著很多很亂统舀,上一家公司主要風(fēng)格就是用純代碼,這一家用的就是xib用的比較多劳景。這幾篇我們就詳細(xì)的介紹一個(gè)xib相關(guān)知識(shí)誉简。
認(rèn)識(shí)一下xib
什么是xib?
xib其實(shí)就是nib轉(zhuǎn)換過來的,nib 和 XIB 都是Interface Builder
的圖形界面設(shè)計(jì)文檔盟广。Interface Builder
把窗口闷串、菜單欄以及窗口上的各種控件的對(duì)象都“凍結(jié)”在了一個(gè) nib檔里面了,程序運(yùn)行時(shí)衡蚂,這些對(duì)象將會(huì)“蘇醒”窿克。
nib
為二進(jìn)制文件,XIB
為純文本文件毛甲,后者方便版本控制年叮,XIB
可編譯為nib
。
xib的創(chuàng)建和視覺顯示
首先我們新建立一個(gè)工程玻募,看下圖只损。
這里,點(diǎn)擊User Interface
中的View和Empty七咧,就可以建立xib文件跃惫,它倆不同的是View是視圖,Empty是空的視圖艾栋。
- empty里面什么都沒有爆存。
- view默認(rèn)帶一個(gè)view視圖。
其它的屬性蝗砾,關(guān)聯(lián)方式都一樣先较。
xib與具體類的關(guān)聯(lián)
在說xib之前,我們看一下storyboard
悼粮,對(duì)于新建立的工程系統(tǒng)會(huì)自帶一個(gè)Main.storyboard
闲勺,這個(gè)storyboard
會(huì)自動(dòng)的關(guān)聯(lián)到新建立的時(shí)候存在的類ViewController
,對(duì)于類的關(guān)聯(lián)扣猫,就是從下圖右側(cè)的輸入框中輸入指定的類名菜循,回車即可,那么這個(gè)storyboard
就關(guān)聯(lián)到那個(gè)類中了申尤。
有人可能要問癌幕,為什么要關(guān)聯(lián)把酶?這個(gè)還是很好理解的吧勺远,你拖進(jìn)去控件當(dāng)然要關(guān)聯(lián)指定的類進(jìn)行處理和顯示了臭杰。
對(duì)于xib同樣如此,也是通過下面方式進(jìn)行關(guān)聯(lián)谚中。
也只有關(guān)聯(lián)后我們才可以將xib中的控件鏈接到關(guān)聯(lián)的類中作為屬性或者觸發(fā)Action等事件,方便我們進(jìn)行詳細(xì)的處理寥枝。
xib和storyboard區(qū)別
下面看一下xib和storyboard區(qū)別宪塔。
-
關(guān)聯(lián)上的區(qū)別
-
XIB
在創(chuàng)建出來的時(shí)候,跟任何文件(類)都沒有關(guān)系囊拜,是一個(gè)單獨(dú)的文件某筐,那么我們?cè)赬IB上所拖拉出來的控件。 -
storyboard
就像每一個(gè)類一樣冠跷,在創(chuàng)建出來的時(shí)候都要指定一個(gè)Class來繼承一下南誊。
-
-
繼承上的區(qū)別
- storyboard自帶繼承關(guān)系。
- XIB在創(chuàng)建出來的時(shí)候沒有人管蜜托,需要我們單獨(dú)再創(chuàng)建一個(gè)類去繼承一下才能夠管理里面的控件屬性抄囚。
-
是否需要主動(dòng)喚醒
- 使用
storyboard
的時(shí)候,不需要用代碼去告訴程序橄务,可以直接運(yùn)行(command + R)的方式去展示storyboard中添加好的控制器和控件幔托。 -
xib
需要我們主動(dòng)喚醒,具體主動(dòng)喚醒后面會(huì)和大家說的蜂挪。
- 使用
xib加載
下面我們看一下xib加載重挑。
首先我新建立一個(gè)xib和對(duì)應(yīng)的view,并將他們進(jìn)行關(guān)聯(lián)和綁定棠涮。
然后將xib設(shè)置為紅色谬哀,方便觀看是否加載成功。
然后我們?cè)赩C中加入這段代碼严肪,就可以正常的喚醒xib了史煎。并將xib的視圖加載到當(dāng)前VC的根View上。
- (void)viewDidLoad
{
[super viewDidLoad];
JJCustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"JJCustomView" owner:nil options:nil] lastObject];
customView.frame = self.view.frame;
[self.view addSubview:customView];
}
這里注意诬垂,就是下面這句話可以喚醒xib
JJCustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"JJCustomView" owner:nil options:nil] lastObject];
這里owner
和options
都暫時(shí)傳遞nil劲室,后面會(huì)具體進(jìn)行說明。
我們?cè)趚ib關(guān)聯(lián)的JJCustomView.m
中加入如下代碼:
@implementation JJCustomView
- (void)awakeFromNib
{
[super awakeFromNib];
NSLog(@"2222");
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
NSLog(@"1111");
}
return self;
}
@end
下面我們看一下調(diào)用棧结窘,這兩個(gè)方法的調(diào)動(dòng)順序很洋,其實(shí)就是先調(diào)用initWithCoder :
方法,后調(diào)用awakeFromNib
方法隧枫。
斷點(diǎn)打到NSLog(@"1111");
這一行喉磁,看一下調(diào)用棧谓苟,如下圖所示。
可以看見协怒,加載完Nib那句代碼涝焙,就調(diào)用initWithCoder :
方法。
放開斷點(diǎn)孕暇,在NSLog(@"2222");
打上斷點(diǎn)仑撞,繼續(xù)看調(diào)用棧。
可以看見妖滔,這里面調(diào)用了一下UINib
的類方法隧哮。
下面我們看一下frame。
@implementation JJCustomView
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"3333 = %@", NSStringFromCGRect(self.view.frame));
}
- (void)awakeFromNib
{
[super awakeFromNib];
NSLog(@"2222 = %@", NSStringFromCGRect(self.frame));
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
NSLog(@"1111 = %@", NSStringFromCGRect(self.frame));
}
return self;
}
看一下輸出結(jié)果
2018-04-11 23:13:28.523315+0800 JJWebImage[1457:58070] 3333 = {{0, 0}, {414, 736}}
2018-04-11 23:14:06.147699+0800 JJWebImage[1457:58070] 1111 = {{0, 0}, {375, 667}}
2018-04-11 23:14:06.148076+0800 JJWebImage[1457:58070] 2222 = {{0, 0}, {375, 667}}
這里座舍,用的是8plus的模擬器沮翔。調(diào)用這兩個(gè)方法的時(shí)候并沒有改變frame,還是xib的自帶的那個(gè)frame曲秉。
除了上面的NSBundle方式加載xib采蚀,還可以通過UINib的方式進(jìn)行加載。
這里參數(shù)bundle參數(shù)傳遞nil承二,就默認(rèn)為[NSBundle mainBundle]
// UINib *nib = [UINib nibWithNibName:@"XibView" bundle:[NSBundle mainBundle]];
UINib *nib = [UINib nibWithNibName:@"XibView" bundle:nil];
NSArray *objs = [nib instantiateWithOwner:nil options:nil];
[self.view addSubview:objs[0]];
SB的加載
前面說的是xib的加載榆鼠,下面我們就看好一下SB的加載。
對(duì)于基于UIViewController
子類的xib的使用矢洲,這種情況下使用很簡(jiǎn)單璧眠,對(duì)VC直接alloc,init
就可以读虏,VC會(huì)自動(dòng)去找自己對(duì)應(yīng)的xib文件责静,即使我們自定義了一些init方法,也不需要對(duì)加載他的xib做處理盖桥,系統(tǒng)會(huì)自動(dòng)幫我們找是否有與其對(duì)應(yīng)的xib文件灾螃。
父類會(huì)判斷有沒有和我們這個(gè)要初始化的VC相同名字的xib文件,如果有就會(huì)加載該xib文件揩徊,如果沒有腰鬼,父類就認(rèn)為我們?cè)揤C沒有xib文件,就會(huì)走正常的init方法塑荒。
后記
本篇主要介紹了xib的一些相關(guān)的基礎(chǔ)知識(shí)熄赡,感興趣的給個(gè)贊或者關(guān)注~~~~