一天一點xib:2初識xib

引言

首先來一個官方說明:

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.

nib文件是描述應用外觀的視覺元素,包含了窗口、視圖、控制和其他,它也可以描述非視覺元素,如你應用中管理窗口和視圖的對象。

通常官方說明都很晦澀,下面淺顯、直白地解釋一下。等等,說好的xib、SB的,怎么還沒開始,就又弄出來了一個nib?別急,現在就開始慢慢道來。

創建Demo工程

我們首先建一個基于single view application模板的工程,叫xibDemo,為了后面演示。然后command + n,調出新建文件的窗口,然后選擇iOS->User Interface->Empty,新建一個空的xib文件,名字叫TestXib,點擊該文件,command + option + 0,調出右邊欄。

在最下面選擇UIView,像拖動文件一樣拖動到中間空白處松手,如果是新版的Xcode,顯示的View可能是正方形的,這是由于xib文件自動開啟了size classes功能,該功能是做適配用的,我們這里為了屏幕顯示全,暫時去掉該功能,然后像剛剛一樣,拖一個UIButton,到這個View,取名hello world。

xib、storyboard、nib總體認識

xib是一個可視化文件,我們通過選中并拖動UI控件到"畫布"上,就能可視化的創建UI控件,并對其進行布局,SB可以理解成為加強版的xib,它功能更加強大,同時也可以理解成為把多個xib文件合成為了一個.storyboard文件,而實際上xib與SB都是xml格式的文件,所以其實我們是可以以兩種方式查看一個xib或SB文件的,這也為我們日后解決xib文件引起的沖突找到了一個突破口。

注:xib、storyboard都屬于資源文件,而不是源文件,這一點十分重要,切記。

nib是經過Xcode編譯之后的,加密的文件,是無法在用Xcode正常打開的,SB文件在編譯之后變成了.storyboardc文件(例如:Main.storyboardc),也是打不開的,兩者都是存放在app的main bundle中。

xib、storyboard文件的創建

xib文件的創建

目前我們簡單的理解:只有UIViewController、UIView的子類才能使用xib文件,他們兩者在創建和使用xib的時候是有所不同的。

1.為UIViewController子類創建對應的xib文件

創建文件的時候勾選also create xib file即可

2.為UIView子類創建xib文件

這個過程比上面要稍微復雜一點,1)先分別創建UIView子類文件和xib文件。2)將兩者建立起關系。通常我們一般習慣將兩者命名為相同的名字,當然,不同也是可以的。給一個類與一個 xib文件建立關系是很重要的一步,具體方法:右邊欄第三個選項(show the identity inspector)下面的custom class-> class中填寫你要與該xib綁定的UIView子類的名字

其實UIView子類創建xib文件的方法也是適用于UIViewController的,只是,我們在創建一個VC類的時候默認有勾選xib的選項,比較方便,如果我們為現有的、且沒有xib文件的VC創建一個xib的話,就用這種方法,其實在早期xcode中,我們創建UIView子類的時候也是可以勾選xib的,只是后來版本的Xcode不提供該功能了。

SB文件的創建

從xib文件的創建我們可以看出,xib文件是與UIViewController或UIView的子類保持一一對應的(一般情況下),但是SB文件卻不然,主要表現在兩個方面:

**1.SB只能被UIViewController的子類使用,并不能被UIView的子類使用。
**

2.SB與UIViewController可以是一對多的關系,一般情況下也往往是如此的。所以,當我們建立了一個.storyboard文件之后并不能像xib一樣往里面拖View了,只能拖VC。

xib、storyboard文件的使用

xib文件的使用

1.基于UIViewController子類的xib的使用

這種情況下使用很簡單,對VC直接alloc,init就可以,VC會自動去找自己對應的xib文件,即使我們自定義了一些init方法,也不需要對加載他的xib做處理,系統會自動幫我們找是否有與其對應的xib文件,例如我們有這樣一個初始化方法:

- (instancetype)initWithCustemData:(id)aData;

我們在創建VC實例的時候可以直接調用這個函數,不用理會xib文件的問題,我們的父類在初始化的時候去自動幫我們找與之對應的xib文件,那么問題來了,父類怎么知道我有沒有xib文件呢?是這樣,父類會判斷有沒有和我們這個要初始化的VC相同名字的xib文件,如果有就會加載該xib文件,如果沒有,父類就認為我們該VC沒有xib文件,就會走正常的init方法。

加載xib的init方法是:

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

如果一旦我們的VC類的名字與對應的xib文件名字不同的時候,我們就必須調用這個初始化方法來創建VC實例了;

[[ViewController alloc] initWithNibName:@"xxx" bundle:[NSBundle mainBundle]]

xxx的地方填那個與我們VC類名不同的那個xib文件的名字,不過一般情況下,我們的VC都與xib保持相同的名字,這里只是想說明,如果名字不同也是可以的。

2.基于UIView子類的xib的使用

TestView *tView = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:self options:nil][0];

上述代碼再次說明xib文件是資源文件,放在main bundle中,@"TestView"是xib文件的名稱,后面兩個參數暫時不用了解,就固定傳self和nil就行,值得說的是,loadNibNamed: owner: options方法返回的是一個數組,而不直接是對象,這是考慮到了Mac開發會有多個對象返回的情況,在iOS開發中就只有一個,固定取[0]就行。

注:一般的UIView對象,代碼初始化的時候都會調用initWithFrame:方法,但是用xib創建的UIView對象是不會調用此方法的,因為該對象的Frame在xib文件中就可以確定了。以xib的形式保存控件對象的過程其實叫做固化(archive),通過xib文件創建控件的過程叫做解固(unarchive),固化是iOS持久化的一種比較好的解決方案,以后有機會會說說iOS持久化的各種方式的優劣,這里不再深入,而與固化相關的初始化函數是:

- (instancetype)initWithCoder:(NSCoder *)aDecoder

所以,當以xib創建UIView對象的時候這個函數會調用,之前在initWithFrame:中要做的事情,可以放在initWithCoder:中,或者放在:

- (void)awakeFromNib
{
    [super awakeFromNib];
    //...
}

該函數會在initWithCoder:后調用,從名字我們就能看出,這個函數的觸發時機是控件已經從xib文件中“解固”之后,兩個函數之間的關系有點像VC的loadView和viewDidLoad之間的關系。

SB文件的使用

由于SB文件與VC一般是一對多的關系,所以我們不僅要知道即將創建的這個VC的實例對象是加載的哪個SB,而且還要知道加載的是該SB中的哪個具體的VC。

SecVC *secVC = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecVC"];

@"Demo"參數代表SB的文件名字,@"SecVC"代表該VC在SB中的ID,具體使用會在下面的文章中提到。個人建議,該ID最好與類名相同,這樣便于將實例化的方法封在基類中。eg:

#import <UIKit/UIKit.h>

@interface GJBasicController : UIViewController

+ (NSString *)gj_storyboardID;
+ (instancetype)gj_controllerInstanceFromStoryboardWithName:(NSString *)aStoryboardName;

@end
#import "GJBasicController.h"

@implementation GJBasicController

+ (NSString *)gj_storyboardID
{
    return NSStringFromClass([self class]);
}

+ (instancetype)gj_controllerInstanceFromStoryboardWithName:(NSString *)aStoryboardName
{
    return [[UIStoryboard storyboardWithName:aStoryboardName bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:[self storyboardID]];
}

@end

總結

本篇文章主要從大處著眼,先對xib有個整體思路上的認識,接下來會細致地學習關于xib的各個方面。

歡迎大家和我交流溝通,文章中有任何錯誤和漏洞,懇請指正,謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容