内容简介:故事板是在 iOS 5 开始出现的,在此之前我们使用的是 nib/xib。一个故事板支持多个 ViewController,同时可以在这些 ViewController 中进行连接(segue)。但是随着工程中 ViewController 的增加,故事板中 ViewController 之间的连线变得纷乱复杂,故事板也就失去了原来的意义。与之相比较,nib/xib 只支持单一的 ViewController,这种因为简单带来的清晰使得它在项目中仍然被大量使用。但是,如果在项目中混合使用故事板和 nib
故事板是在 iOS 5 开始出现的,在此之前我们使用的是 nib/xib。一个故事板支持多个 ViewController,同时可以在这些 ViewController 中进行连接(segue)。但是随着工程中 ViewController 的增加,故事板中 ViewController 之间的连线变得纷乱复杂,故事板也就失去了原来的意义。与之相比较,nib/xib 只支持单一的 ViewController,这种因为简单带来的清晰使得它在项目中仍然被大量使用。
但是,如果在项目中混合使用故事板和 nib 文件,可能会带来一些意想不到的问题。一个典型的问题是,storyboard 加载 nib 中的 view controller 时,这个 view controller 中的 IBOutlet 都会丢失连接,这样在 viewDidLoad 后,所有的 IBOutlet 属性都为 nil,你根本无法使用这些属性。你可以来看一个例子。
-
新建一个 Single View 项目。
-
新建一个 UIViewController 子类,名字叫做 TestViewController,确认勾上 Also create xib file。
-
打开 TestViewController.xib 文件,拖入一个 label,为这个按钮建立一个到 IBOutlet 属性 label 的连接。
-
在 TestViewController.m 的 viewDidLoad 方法中,加入这句:
_label.text = @"我是一个 Label";
同时在这句上打一个断点。
-
打开 Main.storyboard。在 ViewController 上放一个按钮。title 设置为“下一步”。
-
拖入一个 UIViewController。 将 Class 改成 TestViewController。
-
使用 Embed in Navigation Contorller,将 View Controller 外面套上一个导航控制器。
-
在 View Controller 和 TestViewController 之间添加一个 segue,ID 不妨叫做 test。
-
为 View Controller 上的“下一步”按钮创建一个 IBAction buttonClicked,在里面编写代码:
-(void)buttonClicked{ [self performSegueWithIdentifier:@"test" sender:nil];
这样,当按钮一点击,导航控制器会跳到 TestViewController。
Build & run,点击“下一步”按钮,断点停下,将鼠标放在 _label 变量上查看值,发现值为 nil,继续执行,Label 上的文字不会改变。
这个问题说明,故事板在加载 nib 文件时,不会自动加载 nib 文件中的内容。为了搞清楚故事板是如何加载 TestViewController 类的,我们在 TestViewController.m 中增加两个初始化方法,并在每个方法中打上断点:
-(instancetype)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; return self; } -(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; }
Build & run,我们发现断点在 initWithCoder: 方法中停下。说明故事板是调用这个方法来初始化 TestViewController 的。
我们将这个方法修改为:
-(instancetype)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithNibName:NSStringFromClass([self class]) bundle:nil]; return self; }
这样,故事板就会从 nib 文件中加载 TestViewController 了。Build & run,当断点停下,观察 _label 变量,现在它不再为 nil 了:
继续执行,TestViewController 上 Label 的文字成功被我们改变成“我是一个 Label”。
当然,我们也可以用代码创建 TestViewController, 而不是让故事板为我们创建 TestViewController。
在 Main.storyboard 中删除 Test View Controller,然后修改 View Controller 的 buttonClicked 方法:
TestViewController* vc = [TestViewController new]; [self.navigationController pushViewController:vc animated:YES];
效果也是一样的。
以上所述就是小编给大家介绍的《在故事板中加载 nib 时 IBOutlet 为 nil》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 这是 SOFA 的故事,或者也会是你的故事
- 我与 CoffeeScript 的故事
- 我与 CoffeeScript 的故事
- 团队建设活动:巅峰故事
- 我与 CoffeeScript 的故事
- 小小的 Python 编程故事
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Essential C++中文版
[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-8 / 39.80元
书中以4个面向来表现C++的本质:procedural(程序性的)、generic(泛型的)、object-based(个别对象的)、object-oriented(面向对象的),全书围绕着一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性。循此方式,读者不只学到C++的函数和结构,也会学习到它们的设计目的和基本原理。一起来看看 《Essential C++中文版》 这本书的介绍吧!