Anatomy of a Nib File
A nib file describes the visual elements of your application’s user interface, including windows, views, controls, and many others. It can also describe non-visual elements, such as the objects in your application that manage your windows and views. Most importantly, a nib file describes these objects exactly as they were configured in Xcode. At runtime, these descriptions are used to recreate the objects and their configuration inside your application. When you load a nib file at runtime, you get an exact replica of the objects that were in your Xcode document. The nib-loading code instantiates the objects, configures them, and reestablishes any inter-object connections that you created in your nib file
以上是蘋果官方文檔對(duì)nib的晦澀的解釋错览,言簡(jiǎn)意賅的介紹了一下nib是用來(lái)描述應(yīng)用程序的軟件界面练般,視圖面粮,窗體等組件元素毅臊。那么nib到底是什么榕吼?以及和現(xiàn)在我們說(shuō)的XIB有什么關(guān)系呢饿序,先解釋nib,Xcode 3.0 之前 Interface Builder 創(chuàng)建的文件是二進(jìn)制格式 nib,nib 代表 NeXT Interface Builder羹蚣,但是二進(jìn)制并不是那么好管理原探,易讀性也不強(qiáng),Xcode 3.0 之后,為了與時(shí)俱進(jìn)Interface Builder 使用了一種新的文件格式 xib(XML Interface Builder)xib 使用了 XML咽弦,在工程編譯的時(shí)候再轉(zhuǎn)換成 nib徒蟆。XML資源文件更容易被開(kāi)發(fā)者所接受,方便開(kāi)發(fā)型型,也利于解決沖突段审。XIB查看xml格式見(jiàn)以下截圖。
Nib Files
Nib files play an important role in the creation of applications in OS X and iOS. With nib files, you create and manipulate your user interfaces graphically, using Xcode, instead of programmatically.
以上是蘋果官方文檔對(duì)XIB的評(píng)價(jià)和定義:在OS X和iOS應(yīng)用程序的創(chuàng)建中Nib文件扮演著重要角色闹蒜,在Xcode開(kāi)發(fā)工具中用nib文件,你創(chuàng)建和操作用戶界面圖形化,而不是以編程方式寺枉。這句話代表了蘋果對(duì)XIB推薦和重視的態(tài)度,確實(shí)XIB的出現(xiàn)給開(kāi)發(fā)者搭建軟件界面視圖绷落,不用寫(xiě)繁瑣的布局膠性代碼帶來(lái)了福音型凳。XIB是軟件發(fā)展的趨勢(shì),讓編程變得簡(jiǎn)單嘱函,便捷,全民都是開(kāi)發(fā)者埂蕊。
XIB文件的創(chuàng)建
目前在我們iOS應(yīng)用程序的開(kāi)發(fā)中往弓,XIB的使用基本都是基于View類和Controller類去創(chuàng)建的。當(dāng)然只要是展示界面的蓄氧,都可以用XIB去描述函似,UIWindow也是繼承UIView的,此處只描述View類喉童,Controller類撇寞。
基于Controller類
(1) 創(chuàng)建基于UIController子類時(shí)直接勾選創(chuàng)建XIB文件。此時(shí)你可以在XIB文件中拖入控件堂氯,在AppDelegate.m文件中創(chuàng)建該控制器就行了蔑担,cmd+R運(yùn)行正常。
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
ZLController *vc = [[ZLController alloc] init]; // 這種方式咽白,直接用alloc init方式創(chuàng)建就行了啤握。
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
(2) 基于已經(jīng)創(chuàng)建的UIController子類單獨(dú)創(chuàng)建與之對(duì)應(yīng)的XIB文件。
有時(shí)候我們會(huì)有這樣的需求晶框,需求變動(dòng)排抬,想在現(xiàn)有的控制器類創(chuàng)建XIB去描述,cmd+n選擇User interface —>View(Empty)—>雙擊你要選擇與之相關(guān)聯(lián)的類(不用為XIB文件重新命名)授段。
注意:此時(shí)如果還是像上面的方式去創(chuàng)建XIB蹲蒲,直接運(yùn)行會(huì)報(bào)錯(cuò)。錯(cuò)誤提示我們?cè)趧?chuàng)建控制器的時(shí)候無(wú)法加載nib形式的視圖View侵贵。報(bào)錯(cuò)截圖如下届搁。
在這兒有兩種處理方案,切記!?Ъ馈掩宜!當(dāng)然會(huì)涉及一個(gè)很重要又不好說(shuō)清楚的知識(shí)點(diǎn)Nib File’s Owner,先看處理方案的操作么翰,后面會(huì)詳細(xì)介紹Nib File’s Owner牺汤。
方案一:
2.1 還用 alloc init的創(chuàng)建方式,只是需要設(shè)置新建XIB的File’s Owner所關(guān)聯(lián)的類浩嫌,和File’s Owner所管理的View檐迟。
解釋上面截圖的流程:
先選中noXibViewController.xib,點(diǎn)擊File’s Owner码耐,點(diǎn)擊右側(cè)屬性欄中的第三個(gè)標(biāo)簽custom class追迟,關(guān)聯(lián)類,然后點(diǎn)擊左側(cè)的File’s Owner骚腥,按住command鍵敦间,拖拽至下面的View視圖,會(huì)出現(xiàn)Outlets->View束铭,點(diǎn)擊View廓块,這樣就設(shè)置了控制器VC所管理的View,這是關(guān)鍵的一步驟契沫,解決了上面Xcode報(bào)錯(cuò)带猴,而中間一部設(shè)置File’s Owner的custom class 只是這一步的橋梁和過(guò)渡,只有先找到File’s Owner所對(duì)應(yīng)的控制器之后才能找到對(duì)應(yīng)的View視圖懈万。因?yàn)楝F(xiàn)在程序沒(méi)有運(yùn)行拴清,不會(huì)加載到內(nèi)存中,所以如果你不為File’s Owner設(shè)置關(guān)聯(lián)類会通,你直接拖拽設(shè)置File’s Owner的Outlets是不成功的口予,老鐵們可以嘗試一下。如果大家還不理解你可以選中File’s Owner渴语,刪除右邊屬性標(biāo)簽欄的custom class苹威,cmd+R 運(yùn)行成功〖菪祝可能有些老鐵還是迷茫牙甫,這個(gè)File’s Owner所關(guān)聯(lián)的類到底是怎么回事呢?其實(shí)调违,當(dāng)我們運(yùn)行程序時(shí)窟哺,在AppDelegate.m文字中,我們用alloc init的方式創(chuàng)建了VC控制器技肩,Xcode會(huì)自動(dòng)關(guān)聯(lián)尋找與此類(noXibViewController)同名的xib資源文件且轨,如果找到了會(huì)自動(dòng)加載浮声,所以才不會(huì)報(bào)錯(cuò)。特殊情況旋奢,如果你為XIB起名和要關(guān)聯(lián)的類名不相同泳挥,用alloca init 去創(chuàng)建XIB 系統(tǒng)是找不到該xib文件的,當(dāng)然也會(huì)報(bào)錯(cuò)至朗,切記L敕!锹引!
這兒的處理方式矗钟,分兩步走:
(1)修改創(chuàng)建VC的方式,不用alloc init了嫌变,明確的告訴它需要加載的XIB名稱
noXibViewController *vc = [[noXibViewController alloc] initWithNibName:@"View" bundle:[NSBundle mainBundle]];
(2) 在控制面板中關(guān)聯(lián)類和設(shè)置XIB的File’s Owner(注意一定要設(shè)置XIB父視圖吨艇,而不是subViews)。此處截圖上上面類似腾啥。
基于View類
初級(jí)的用法和基于控制器Controller的用法一樣的东涡,
(1) 新建View的子類.h,.m文件
(2) 新建XIB文件倘待,選中對(duì)應(yīng)的類文件
(3) 關(guān)聯(lián)XIB文件和類文件(這所以要關(guān)聯(lián)類文件软啼,是為了方便連線,代碼控制XIB)
(4) 在控制器類加載xib文件(此處不講解封裝性延柠,只講解原理)
這兒在控制器VC中加載XIB基本有兩種方案。
self.view.backgroundColor = [UIColor whiteColor];
// 方案一 加載對(duì)應(yīng)的XIB文件锣披,設(shè)置owner(nil贞间,0,self) 效果是一樣的,可能蘋果內(nèi)部做了判斷雹仿,默認(rèn)都是self(本控制器),也就是這個(gè)通過(guò)XIB實(shí)例化的View的資源文件的所有者和用戶交互的管理者增热。
customView *customView = [[[NSBundle mainBundle] loadNibNamed:@"customView" owner:self options:0] objectAtIndex:0];
// 方案二 1.先取出nib文件 2.nib對(duì)象方法取出對(duì)應(yīng)數(shù)組中想要的XIB資源文件
UINib *nib = [UINib nibWithNibName:@"customView" bundle:[NSBundle mainBundle]];
UIView *customView = [[nib instantiateWithOwner:self options:0] lastObject];
customView.frame = CGRectMake(0, 64, self.view.frame.size.width, customView.frame.size.height);
[self.view addSubview:customView];
注意:基于View的XIB文件加載方式只能是加載資源文件的方式,這點(diǎn)和基于Controller的 alloca init 加載XIB的方式是不同的胧辽,可能是蘋果內(nèi)部沒(méi)有做處理峻仇,它的父類不會(huì)去匹配和此類(customView)同名的XIB文件,所以不能用alloc init的方式去加載邑商。
XIB自定義布局控件
XIB是以可視化視圖的方式創(chuàng)建了軟件界面摄咆,簡(jiǎn)單的說(shuō)我們用Interface Builder 方式創(chuàng)建了UIView對(duì)象就定義了View的大小,位置人断,背景吭从,圖層(注意:用XIB拖拽控件只能是往View上拖拽,XIB目前只支持這種形式恶迈,例如涩金,UIImageView上添加UIButton是能用代碼的方式添加),那么,initWithFrame方法是不會(huì)被調(diào)用的,一般情況下我們用代碼的方式創(chuàng)建View或者UIView的子類對(duì)象時(shí)候才會(huì)調(diào)用initWithFrame方法步做,
initWithFrame方法用來(lái)初始化并返回一個(gè)新的視圖對(duì)象,根據(jù)指定的CGRect
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];// 先調(diào)用父類的initWithFrame方法
if (self) {
// 再自定義該類(UIView子類)的初始化操作副渴。
_button = [[UIButton alloc] initWithFrame:self.bounds];
[_button setFrame:CGRectMake(0, 0, 320, 480)];
[self addSubview: _button];
}
return self;
}
當(dāng)我們用Interface Builder創(chuàng)建View的時(shí)候不會(huì)再去調(diào)用initWithFrame方法,但是XIB資源文件創(chuàng)建保存的過(guò)程會(huì)調(diào)用全度,所以可以把以前放在initWithFrame方法中做的事情放在這個(gè)函數(shù)里面處理煮剧,可以重新定義視圖。
- (instancetype)initWithCoder:(NSCoder *)aDecoder
當(dāng)然同樣也會(huì)調(diào)用下面的函數(shù)讼载,從字面的意思可以看出awakeFromNib在initWithCoder方法之后調(diào)用轿秧,此刻是喚醒XIB視圖文件,可以在此函數(shù)中進(jìn)行調(diào)整咨堤,這樣的話你就可以根據(jù)需求進(jìn)行編碼了菇篡。
-(void)awakeFromNib
{
[super awakeFromNib];
// 布局
}
總結(jié)
XIB是蘋果官方推薦的視圖開(kāi)發(fā)方案也是我們開(kāi)發(fā)者必備技能。此篇文章初對(duì)XIB做了簡(jiǎn)單介紹一喘,創(chuàng)建兩種不同XIB文件需要注意的事項(xiàng)驱还,流程,歸納和比較凸克。下一篇文章將會(huì)繼續(xù)講解XIB议蟆,主要是XIB一些高級(jí)用法。
-END-
文章寫(xiě)得有點(diǎn)亂,Markdown語(yǔ)法還不是太熟練萎战,喜歡的老鐵們咐容,評(píng)論走一走,敬請(qǐng)留言蚂维,如果文章有不妥之處我會(huì)及時(shí)更正戳粒。