1、解決問題
Xib/Storybarod能夠方便、可視化的設置約束,在開發中也愈來愈重要。因爲Xib不能組件化,使得封裝、重用都變得不可行。本文將介紹一種解決方案,來實現Xib組件化。數組

2、模型塊原理
在介紹原理以前,咱們先弄清楚兩個概念:ide

從上圖能夠看出,分別選中File’s Owner及根視圖View,都有Custom Class屬性面板。其中Class屬性,有什麼做用,區別又是什麼呢?模塊化
2.1 View的Class屬性
View的Class屬性用於指定選中的視圖的實例化類。Xib其實是一個XML文件,在加載時,解析邏輯會根據XML內容,建立並設置View實例。而此處的Class就是告訴解析邏輯,想要建立什麼類的實例。若是此處設置爲UIButton,則解析邏輯會生成一個UIButton的實例。工具
2.2 File’s Owner的Class屬性
Feile’s Owner的Class屬性,大部分狀況下,都爲UIViewController及其子類。組件化
1 |
|
從上面xib的加載接口能夠看出,加載Xib須要指定一個owner類的實例,解析邏輯並無像2.1建立新實例,而是使用參數名爲owner的已建立好的實例。post
若是沒有建立,爲何還要指定File's Owner的Class屬性?
此處設置的Class屬性值,主要做用是經過關鍵字@IBOutlet,聲明有哪些屬性及方法能夠創建關聯關係。解析邏輯會將關聯視圖的引用賦值給owner的對應屬性,觸發事件則執行owner.method()方法。目的爲了在owner中,就能夠方便的處理界面相關的業務邏輯。能夠這樣理解,File’s Owner的Class,是關聯接口聲明,loadNibNamed傳入的owner是實現。ui
Tips
File’s Owner的Class屬性,起一個聲明做用,告知哪些屬性及方法可使用。spa
1 |
class ILViewController: UIViewController { |
既然如此(如上面代碼),使用loadNibNamed方法加載Xib時,owner參數傳入ILViewController實例,而Xib中File’s Owner的Class卻設置爲ILFlagController,是否可行?答案:可行。設計
2.4 Xib模塊化原理
在Storybarod/Xib中,與組件化有關的只有視圖的Class屬性。視圖是由xib解析邏輯建立,因此要實現組件化,就要在此Class實例化時,自動執行加載子xib模塊的功能。
3、工具類源碼
爲了實現xib的模塊化,須要有一個小的功能類:
1 |
import UIKit |
4、實戰示例
4.1 封裝Xib組件
新建ILDemoView.xib、ILDemoView.swift兩個文件(文件名要相同),並將ILDemoView文件的File’s Owner的Class設置爲ILDemoView
1 |
class ILDemoView: ILXibView { |
在xib文件中添加UILabel,並關聯到ILDemoView中

4.2 使用Xib組件
新建Xib/Storyboard文件,添加一個UIView控件,並將此控件的Class屬性設置爲ILDemoView

Tips
使用的時候,先設置目標UIView的Class屬性爲ILDemoView,再將此UIView控件拖拽創建關聯關係,會發現此時代碼中屬性類型已自動設置爲ILDemoView。ILXibView簡單卻很是實用,咱們項目中已經大量的使用它,對於Xib的模塊化封裝,絕對是一利器。
之前使用xib時一直都有點疑問,xib中能夠有多個視圖控件,可是從xib中load出來的是一個數組,那麼怎麼肯定哪一個對象對應的是哪一個控件呢?
能夠實踐一下:
PurpleView.xib
隨便在xib文件中加了幾個視圖。
接下來將其load出來看看:
MainViewController.m
1
2
3
4
5
6
7
8
9
|
- (void)logViewsFromXIB {
NSLog(@
"%s begin"
, __func__);
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@
"PurpleView"
owner:nil options:nil];
for
(int i = 0; i < views.count; i++) {
id obj = views[i];
NSLog(@
"%d : %@"
, i, [obj class]);
}
NSLog(@
"%s end"
, __func__);
}
|
控制檯輸出以下:
1
2
3
4
5
6
|
2015-01-09 15:03:06.629 JLN-1_xib[3139:121677] -[MainViewController logViewsFromXIB] begin
2015-01-09 15:03:06.635 JLN-1_xib[3139:121677] 0 : UIView
2015-01-09 15:03:06.635 JLN-1_xib[3139:121677] 1 : UIButton
2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] 2 : UITableView
2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] 3 : UILabel
2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] -[MainViewController logViewsFromXIB] end
|
結論:
從xib中load出來的views數組中視圖對象的排列順序和xib scene中的對象排列順序一致(其實就是xml文件中元素的排序而已)。以下:
能夠將其打亂並從新運行程序查看結果。
直接下載demo
2016.8.2更新
感謝 霰雪 檢查出ILXibView在6S不居中對齊問題,文章已經更新,感謝你們的支持。