iOS AutoLayout: 关联 Xib 和 UIViewController

今天主要跟大家分享两个内容
* UIViewController 如何作为 Xib 的 File’s Owner
* Xib 中的组件如何和 UIViewController 连线

创建工程 MZXibAndVC

简单的创建一个 Single View 的 iOS 工程即可.

创建 xib 文件 View.xib

新建文件/iOS/UserInterface View/Empty

编辑 View.xib

不使用 Size Classes
增加一些用来测试的组件, 效果如下.
图1

和 UIVIewController 关联

第一步, 选择 View.xib, 并选择 File’s Owner 选项
在 Custom Classes 中填写需要关联的 ViewController.

图2

第二步, 关联 View

按住 control, 从 File’s Owner 拖线到 View, 如图

图3

在出现的提示框中, 选择 View, 如图, 松手即可完成绑定.

图4

完成之后, 你可以看到, 如图所示的效果.

图5
图6

第三步, 展示关联的视图.

在 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 中即可.

图7

完成连线, 再次编译运行.

运行报错了:
图8

发生这种错误的原因是因为, 连线的组件无法关联或是找不到 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.

©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页