假设我有一个包含单个根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>
欢迎提出任何建议。
答案 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。