本文只适合初学者看,大神可以绕行,或者帮小弟补充
『我一直在想XIB到底是什么?其实XIB特别简单,XIB就是nib转变过来的!那么nib又是什么?如果说你是早期的开发人员,可能很清楚两者之间的关系。但目前我对两者的理解还很少。查了相关资料是这样说的(引用了别人的资料)』
相同点:
nib 和 XIB 都是 Interface Builder 的图形界面设计文档。Interface Builder 把窗口、菜单栏以及窗口上的各种控件的对象都“冻结”在了一个 nib档里面了;程序运行时,这些对象将会“苏醒”。
不同点:
nib为二进制文件,XIB为纯文本文件,后者方便于版本控制和Diff。XIB 可编译为 nib。
如果是你初学者,可能看着有点晕晕的。那么现在我们来看一下XIB是什么??我们如何知道和了解到她
一、初识XIB
在我们创一个项目时会看到User Interface,注意的是会出现一个空的视图和一个带view的视图。当我们点击的任何一个文件的时候都会在项目中产生相关的XIB文件(注意:只是一个,这里为了展示效果,我创建出来了两个)
那么问题来了
空的XIB和带一个view的XIB有什么区别?
我个人在XIB的使用上不多,目前还真没发现区别,但我想Xcode这样设计肯定是有原因的,如果你有想法可以留言给我
创建好了,接下来XIB如何使用?
二、XIB的使用
- 简单理解:
其实XIB在使用上非常类似storyboard(第一遍提到)。什么意思呢?storyboard是可以创建多个控制器或者是视图,在工作职责上来看会有很多的作用。而XIB呢?实际是一个小视图,更多是将带有复杂性和有共性的问题单一处理掉。不知道我这么说你会不会理解。如果不是很清楚,那你就可以理解为:模板化(视图)
这里说句题外话:学习IOS的时候,必须要保持一个思想,就是复杂问题简单化,其实无论在学习和生活中,我们在遇到任何问题或者事情的时候都应该有这样的思维方式
- 观察一下界面:
在使用上,XIB与storyboard非常类似(第二遍提到),一样可以拖拉拽,去设置属性以及相应的方法。但当你创建一个XIB的时候你会发现XIB的界面中右侧(控制器或者控件的区域)控件会出现在最上面,而控制器呢?会出现在最下面,看下图:
很细微的举动告诉我们。XIB与storyboard在工作的侧重点是完全不一样的。XIB更喜欢去添加控件,而storyboard则是喜欢去添加控制器。
『区别1:侧重点不同,导致工作承担的职责就不同』
- 使用:
1、XIB在创建出来的时候,跟任何文件(类)都没有关系,是一个单独的文件,那么我们在XIB上所拖拉出来的控件,我们应该如何去管理呢?又或者说如何去获取到这些控件呢?
想想Xcode在创建一个空项目出来的时候是怎么做的,都有哪些文件,我们在storyboard中创建的控件又拖线到哪里去了呢?再仔细看看下面的图??
没错,storyboard在创建出来的时候,身份检测器中Class自动继承了一个控制器,这个控制器正是我们在创建项目的时候系统给我们自带的一个类。这说明什么?
说明一个storyboard就像每一个类一样,在创建出来的时候都要指定一个Class来继承一下
那么我们在创建一个XIB的时候,是不是也要这么做呢??没错,我们也需要创建一个类来管理我们自己单独创建出来的XIB,管理就意味这在XIB中所拖拉出来的控件一定是放在这个类里的,去设置属性和监听动作等等
『区别2:继承管理问题:storyboard自带继承关系,有人管。而XIB在创建出来的时候没有人管,需要我们单独再创建一个类去继承一下才能够管理里面的控件属性』
2、在使用storyboard的时候,我们不需要用代码去告诉程序,「我要运行storyboard了」。我们可以直接运行(command + R)的方式去展示storyboard中添加好的控制器和控件即可。
而XIB就不是了,她需要我们来『唤醒』,这个词可以在别的资料中也能看到,但怎么理解这个唤醒就不要太深究了。只理解为,我们必须要通过代码来告诉程序xib也是我们需要加载的视图:
『区别3:主动唤醒:没人管就算了,还那么懒,必须还要叫醒』
三、XIB内部实现问题
我们在管理XIB的文件中要告诉程序两件事情
- 加载XIB
- 给XIB里的控件赋值(重写模型属性的set方法)
第一件事情:加载XIB
+ (instancetype)LoadXIB {
return [[[NSBundle mainBundle] loadNibNamed:@"XXX" owner:nil options:nil] lastObject];
//xxx是XIB的名称
}
这句代码分解4部分:(return就不解释了)
1、[NSBundle mainBundle] :是专门加载路径的一句代码,如果想加载别的也可以使用这句,比如:
NSString *path = [[NSBundle mainBundle] pathForResource:@"xxx.plist" ofType:nil]
2、loadNibNamed:@"XXX" 加载路径里的NIB名称为:@"XXX"
3、owner:nil options:nil] 基本都为nil,帮助文件对这两个参数是这么说的
- owner:
The object to assign as the nib’s File's Owner object(字幕:请求翻译~) - options
A dictionary containing the options to use when opening the nib file. For a list of available keys for this dictionary, see Nib File Loading Options.(字幕:请求翻译~)
4、 lastObject] 这个就有意思了。为什么是lastObject,当然firstObject也可以。这让我们想到了数组。而帮助文件是这么解释的
- An array containing the top-level objects in the nib file.(字幕:请求翻译~)
我理解的是:其实XIB就是一个视图,当然我们不只放一个控件(或许会放一个),我们需要返回最顶部的一个对象给她,就好比OC里的数组第一个元素的地址就是这个数组的地址是一个意思。获取到的最顶部对象就能代表这个XIB自身。那谁来接收这个对象呢?恰恰就是XIB的管理者来接收,下面就是通过类方法来调用
// 对照上面的类方法看一下
LoadXIBView *XIB = [LoadXIBView LoadXIB];
第二件事情:给XIB里的属性进行赋值(或重写模型属性的set方法)
在赋值的时候需要我们注意,XIB里的控件不只是一个,或许有按钮,或许有图片,或许还有别的等等……(一个数组)那么控件的数量是不是应该跟我们从网络(本地加载)的数据应该是一一对应的呢??也就是说,我们获取到的数据和想展示的出来的控件应该是对应有值的。如果没值,那就是nil 所以在我们赋值的时候,应该是逐一赋值好呢?还是应该把模型当成自己的属性,然后重写属性的set方法,然后在set里面给模型属性赋值呢??
说到这,XIB的使用基本算是完成了,然后日后如果我有新的理解方式我会继续更新的,这里先说到这些。接下来我们应该想想,管理XIB的文件.h与.m中应该怎么写??写些什么??(封装加载XIB的类方法和模型属性的set方法,引入模型作为属性)