今天主要跟大家分享两个内容
* UIViewController 如何作为 Xib 的 File’s Owner
* Xib 中的组件如何和 UIViewController 连线
创建工程 MZXibAndVC
简单的创建一个 Single View 的 iOS 工程即可.
创建 xib 文件 View.xib
新建文件/iOS/UserInterface View/Empty
编辑 View.xib
不使用 Size Classes
增加一些用来测试的组件, 效果如下.
和 UIVIewController 关联
第一步, 选择 View.xib, 并选择 File’s Owner 选项
在 Custom Classes 中填写需要关联的 ViewController.
第二步, 关联 View
按住 control, 从 File’s Owner 拖线到 View, 如图
在出现的提示框中, 选择 View, 如图, 松手即可完成绑定.
完成之后, 你可以看到, 如图所示的效果.
第三步, 展示关联的视图.
在 ViewController 的 viewDidload 方法中
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *v = [[UIViewController alloc] initWithNibName:@"View" bundle:nil].view;
v.frame = self.view.bounds;
[self.view addSubview:v];
}
编译运行项目, 你会看到效果.
这个时候, 你已经成功关联 xib 并可以展示视图了.
接下来, 我们希望在 ViewController 中改变 xib 中 label 的 text.
很简单, 直接托线到 ViewController 中即可.
完成连线, 再次编译运行.
运行报错了:
发生这种错误的原因是因为, 连线的组件无法关联或是找不到 owner.
解决这个问题很简单.
修改一下 ViewController 中的 viewDidload 实现
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 加载方式错误
#if 0
UIView *v = [[UIViewController alloc] initWithNibName:@"View" bundle:nil].view;
v.frame = self.view.bounds;
[self.view addSubview:v];
#endif
UIView *v = [[[NSBundle mainBundle] loadNibNamed:@"View" owner:self options:nil] lastObject];
v.frame = self.view.bounds;
[self.view addSubview:v];
}
再次运行, 还是报错:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'
错误很明显, 自己添加自己了.
换句话说, v 和 self.view 是同一个对象.
解决方案:
去掉
[self.view addSubview:v];
可以通过 log 来观察两个视图之间的关系:
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UILabel *mylab;
@property (strong, nonatomic) IBOutlet UIImageView *myphoto;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 加载方式错误
#if 0
UIView *v = [[UIViewController alloc] initWithNibName:@"View" bundle:nil].view;
v.frame = self.view.bounds;
[self.view addSubview:v];
#endif
UIView *v = [[[NSBundle mainBundle] loadNibNamed:@"View" owner:self options:nil] lastObject];
v.frame = self.view.bounds;
NSLog(@"v = %@", v);
NSLog(@"self.view = %@", self.view);
NSLog(@"v == self.view? %i", (v == self.view));
self.mylab.text = @"Comeon";
// 自己不可以 add 自己
//[self.view addSubview:v];
}
另外, 还有一种从 xib 加载ViewController 的方式:
-(instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil
可以移步 iOS AutoLayout: 从 XIB 中加载UIViewController.
下篇具体给大家探讨 UIView 关联 xib.