以自身作为文件所有者从 XIB 文件实例化 UIView?



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

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

换句话说,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)时,应用程序崩溃了。

我错过了什么明显的吗?还是我的理解有缺陷?

一般的问题是,我只是想有一个自定义的UIView子类与关联的XIB,其中包含该视图的可视化表示,我还希望能够关联iboutlet之间的XIB和它相应的UIView子类。

欢迎大家提出建议

经过一番挖掘,我找到了一个解决方法。基本上,我没有将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.

最新更新