从XIB文件中实例化UIView,并将自身作为文件的所有者?

时间:2014-05-22 03:23:39

标签: ios uiview interface-builder xib

假设我有一个包含单个根UIView的XIB文件(MyView.xib),其类是一些自定义UIView子类(MyView)。

我想从XIB文件创建一个MyView实例(在代码中),但我也希望文件的所有者是MyView本身的实例(这样我就可以将IBOutlets从XIB链接到代码)。

换句话说,MyView是XIB中根视图的类,它也被设置为文件的所有者类。

我在MyView实现中尝试过类似的内容:

- (id)initFromNib {
    self = [[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil] firstObject];
    return self;
}

然后我意识到这没有意义,因为那时self是nil,所以文件的所有者设置为nil(不好)。

这开始感觉像是鸡蛋问题,因为我需要文件的所有者在创建之前成为即将创建的实例。

然后我尝试了这样的事情:

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:CGRectMake(0.0, 0.0, 310, 166)];
    if (self) {
        self = [[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil] firstObject];
    }
    return self;
}

显然,这只是一个暂时的黑客,只是为了看它是否会起作用,但是没有。视图加载并正确显示但是当我按下其中一个按钮(具有相关的IBActions)时应用程序崩溃。

我错过了一些明显的东西吗?或者我的理解在某种程度上有缺陷?

一般的问题是我只想拥有一个带有关联XIB的自定义UIView子类,它包含该视图的可视化表示,我还希望能够在XIB和相应的UIView子类之间关联IBOutlet。 / p>

欢迎提出任何建议。

1 个答案:

答案 0 :(得分:2)

经过一番挖掘后,我发现了一种解决方法。基本上不是将我的IBOutlets和IBActions链接到文件的所有者,而是将它们直接链接到根视图的类(通过自定义子类公开了IB属性)。

关键是不要依赖文件的所有者,而是将出口和操作直接连接到自定义视图。

这是我最终使用的初始化程序:

- (instancetype)initFromNib {
    return [[[NSBundle mainBundle] loadNibNamed:@"MyView" owner:nil options:nil] firstObject];
}

现在这似乎工作正常。

<强>更新

我在UIView上创建了一个类别,用于从XIB初始化视图(它假定XIB名称与类名相同)。

<强>的UIView + Initialization.h

#import <UIKit/UIKit.h>

@interface UIView (Initialization)

- (instancetype)initFromNib;

@end

<强>的UIView + Initialization.m

#import "UIView+Initialization.h"

@implementation UIView (Initialization)

- (instancetype)initFromNib {
    return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:nil options:nil] firstObject];
}

@end

然后你可以简单地做:

MyView *myView = [[MyView alloc] initFromNib];

假设您有一个MyView.xib文件,其根视图的类是MyView。