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不居中对齐问题,文章已经更新,感谢你们的支持。