inheritance从nib加载的UIView子类
我有一个类, FooView
,这是UIView
的子类,其视图是从一个笔尖加载,如下所示:
+ (instancetype)viewFromNib { NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"FooView" owner:self options:nil]; return [xib objectAtIndex:0]; }
笔尖本身的自定义类在Identity Inspector中设置为FooView
。
这被实例化为:
FooView *view = [FooView viewFromNib];
这就像你所期望的那样。 但是,当FooView本身被子类化为FooSubclassView,并且实例化为:
FooSubclassView *view = [FooSubclassView viewFromNib];
view
仍然是FooSubclassView
types,而不是FooSubclassView
。
使用object_setClass
调整类并不能解决底层对象是FooView实例的问题,因此在子类实例上调用的方法将是超类( FooSubclassView
)的方法,而不是FooSubclassView
。
我怎样才能纠正这个问题,使子类是正确的types,而不必为每个子类创build一个新的笔尖,或者不得不在每个子类中重新实现viewFromNib
?
Swizzling不是(永远)答案。
问题在于你的NIB; 它被归档为对象[0]是FooSubclassView
一个实例,而不是FooSubclassView
。 如果要使用与对象[0] 不同的视图子类加载相同的 NIB,则需要将实例移出NIB的存档。
可能是最容易做的事情,因为你的类已经加载了NIB,所以使FooSubclassView
或FooSubclassView
的实例成为文件的所有者 。
这个问题有一个文件的所有者模式的体面的解释。 请注意,你已经在那里了,因为你的类正在加载XIB / NIB。
这里是文件所有者的官方文档 。
我不确定你是否find了最好的解决scheme,但我认为这是你正在寻找的。
+ (instancetype)viewFromNib { NSString *className = NSStringFromClass([self class]); NSArray *xib = [[NSBundle mainBundle] loadNibNamed:className owner:self options:nil]; return [xib objectAtIndex:0]; }
只要你能确定NIB与class级同名,
在意识到我错误的要求之一后,我说我必须同意@ bbum。
- (id)init { // NOTE: If you don't know the size, you can work this out after you load the nib. self = [super initWithFrame:GCRectMake(0, 0, 320, 480)]; if (self) { // Load the nib using the instance as the owner. [[NSBundle mainBundle] loadNibNamed:@"FooView" owner:self options:nil]; } return self; } + (instancetype)viewFromNib { return [[self alloc] init]; }