iOS 浅谈XIB应用(一)

图片来自简书App.jpg

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

以上是苹果官方文档对nib的晦涩的解释,言简意赅的介绍了一下nib是用来描述应用程序的软件界面,视图,窗体等组件元素。那么nib到底是什么?以及和现在我们说的XIB有什么关系呢,先解释nib,Xcode 3.0 之前 Interface Builder 创建的文件是二进制格式 nib,nib 代表 NeXT Interface Builder,但是二进制并不是那么好管理,易读性也不强,Xcode 3.0 之后,为了与时俱进Interface Builder 使用了一种新的文件格式 xib(XML Interface Builder)xib 使用了 XML,在工程编译的时候再转换成 nib。XML资源文件更容易被开发者所接受,方便开发,也利于解决冲突。XIB查看xml格式见以下截图。

Snip20170712_37.png

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. 

以上是苹果官方文档对XIB的评价和定义:在OS X和iOS应用程序的创建中Nib文件扮演着重要角色,在Xcode开发工具中用nib文件,你创建和操作用户界面图形化,而不是以编程方式。这句话代表了苹果对XIB推荐和重视的态度,确实XIB的出现给开发者搭建软件界面视图,不用写繁琐的布局胶性代码带来了福音。XIB是软件发展的趋势,让编程变得简单,便捷,全民都是开发者。

XIB文件的创建

目前在我们iOS应用程序的开发中,XIB的使用基本都是基于View类和Controller类去创建的。当然只要是展示界面的,都可以用XIB去描述,UIWindow也是继承UIView的,此处只描述View类,Controller类。

基于Controller类

(1) 创建基于UIController子类时直接勾选创建XIB文件。此时你可以在XIB文件中拖入控件,在AppDelegate.m文件中创建该控制器就行了,cmd+R运行正常。


Snip20170712_33.png
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    ZLController *vc = [[ZLController alloc] init]; // 这种方式,直接用alloc init方式创建就行了。
   UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:vc];
   self.window.rootViewController = nav;
   [self.window makeKeyAndVisible];

(2) 基于已经创建的UIController子类单独创建与之对应的XIB文件。
有时候我们会有这样的需求,需求变动,想在现有的控制器类创建XIB去描述,cmd+n选择User interface —>View(Empty)—>双击你要选择与之相关联的类(不用为XIB文件重新命名)。


Snip20170712_35.png
注意:此时如果还是像上面的方式去创建XIB,直接运行会报错。错误提示我们在创建控制器的时候无法加载nib形式的视图View。报错截图如下。

Snip20170712_36.png

在这儿有两种处理方案,切记!!!当然会涉及一个很重要又不好说清楚的知识点Nib File’s Owner,先看处理方案的操作,后面会详细介绍Nib File’s Owner。
方案一:
2.1 还用 alloc init的创建方式,只是需要设置新建XIB的File’s Owner所关联的类,和File’s Owner所管理的View。
Snip20170712_41.png

解释上面截图的流程:
先选中noXibViewController.xib,点击File’s Owner,点击右侧属性栏中的第三个标签custom class,关联类,然后点击左侧的File’s Owner,按住command键,拖拽至下面的View视图,会出现Outlets->View,点击View,这样就设置了控制器VC所管理的View,这是关键的一步骤,解决了上面Xcode报错,而中间一部设置File’s Owner的custom class 只是这一步的桥梁和过渡,只有先找到File’s Owner所对应的控制器之后才能找到对应的View视图。因为现在程序没有运行,不会加载到内存中,所以如果你不为File’s Owner设置关联类,你直接拖拽设置File’s Owner的Outlets是不成功的,老铁们可以尝试一下。如果大家还不理解你可以选中File’s Owner,删除右边属性标签栏的custom class,cmd+R 运行成功。可能有些老铁还是迷茫,这个File’s Owner所关联的类到底是怎么回事呢?其实,当我们运行程序时,在AppDelegate.m文字中,我们用alloc init的方式创建了VC控制器,Xcode会自动关联寻找与此类(noXibViewController)同名的xib资源文件,如果找到了会自动加载,所以才不会报错。特殊情况,如果你为XIB起名和要关联的类名不相同,用alloca init 去创建XIB 系统是找不到该xib文件的,当然也会报错,切记!!!
这儿的处理方式,分两步走:
(1)修改创建VC的方式,不用alloc init了,明确的告诉它需要加载的XIB名称

    noXibViewController *vc = [[noXibViewController alloc] initWithNibName:@"View" bundle:[NSBundle mainBundle]];

(2) 在控制面板中关联类和设置XIB的File’s Owner(注意一定要设置XIB父视图,而不是subViews)。此处截图上上面类似。

Snip20170713_2.png
基于View类

初级的用法和基于控制器Controller的用法一样的,

(1) 新建View的子类.h,.m文件
(2) 新建XIB文件,选中对应的类文件
(3) 关联XIB文件和类文件(这所以要关联类文件,是为了方便连线,代码控制XIB)
(4) 在控制器类加载xib文件(此处不讲解封装性,只讲解原理)

这儿在控制器VC中加载XIB基本有两种方案。

   self.view.backgroundColor = [UIColor whiteColor];
    // 方案一  加载对应的XIB文件,设置owner(nil,0,self) 效果是一样的,可能苹果内部做了判断,默认都是self(本控制器),也就是这个通过XIB实例化的View的资源文件的所有者和用户交互的管理者。
    customView *customView = [[[NSBundle mainBundle] loadNibNamed:@"customView" owner:self options:0] objectAtIndex:0];
    // 方案二  1.先取出nib文件 2.nib对象方法取出对应数组中想要的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文件加载方式只能是加载资源文件的方式,这点和基于Controller的 alloca init 加载XIB的方式是不同的,可能是苹果内部没有做处理,它的父类不会去匹配和此类(customView)同名的XIB文件,所以不能用alloc init的方式去加载。

XIB自定义布局控件

XIB是以可视化视图的方式创建了软件界面,简单的说我们用Interface Builder 方式创建了UIView对象就定义了View的大小,位置,背景,图层(注意:用XIB拖拽控件只能是往View上拖拽,XIB目前只支持这种形式,例如,UIImageView上添加UIButton是能用代码的方式添加),那么,initWithFrame方法是不会被调用的,一般情况下我们用代码的方式创建View或者UIView的子类对象时候才会调用initWithFrame方法,
initWithFrame方法用来初始化并返回一个新的视图对象,根据指定的CGRect

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];// 先调用父类的initWithFrame方法
    if (self) {
        // 再自定义该类(UIView子类)的初始化操作。
        _button = [[UIButton alloc] initWithFrame:self.bounds];
        [_button setFrame:CGRectMake(0, 0, 320, 480)];        
        [self addSubview: _button];
    }
    return self;
}

当我们用Interface Builder创建View的时候不会再去调用initWithFrame方法,但是XIB资源文件创建保存的过程会调用,所以可以把以前放在initWithFrame方法中做的事情放在这个函数里面处理,可以重新定义视图。

- (instancetype)initWithCoder:(NSCoder *)aDecoder

当然同样也会调用下面的函数,从字面的意思可以看出awakeFromNib在initWithCoder方法之后调用,此刻是唤醒XIB视图文件,可以在此函数中进行调整,这样的话你就可以根据需求进行编码了。

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

总结

XIB是苹果官方推荐的视图开发方案也是我们开发者必备技能。此篇文章初对XIB做了简单介绍,创建两种不同XIB文件需要注意的事项,流程,归纳和比较。下一篇文章将会继续讲解XIB,主要是XIB一些高级用法。

-END-

文章写得有点乱,Markdown语法还不是太熟练,喜欢的老铁们,评论走一走,敬请留言,如果文章有不妥之处我会及时更正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 译者注:本文是对 Apple 官方文档的翻译,原文地址为:https://developer.apple.com/...
    ampire_dan阅读 7,404评论 0 13
  • 关于资源 适用于计算机程序的资源是与程序可执行代码相关的数据文件。资源可以通过将代码之外的复杂数据集或图形内容创建...
    nicedayCoco阅读 631评论 0 0
  • 首先声明,我这是根据别人的讲解来写出来的,,, 一、关于xib 1.xib和nib 在程序里面我们看到的基本上是U...
    湮灭_尘事阅读 3,577评论 1 14
  • 大多数Ios开发者都喜欢运用xib以及约束来布局,这样省去了大量初始化代码,但是xib的使用也是存在不少差异的: ...
    Hanser0503阅读 9,654评论 1 6
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,134评论 30 470