ios 从nib加载自定义UIView,nib中包含的所有子视图都是nil?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7588066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loading custom UIView from nib, all subviews contained in nib are nil?
提问by strahlr
I have a custom UIView
object with a nib
that defines the view/subview layout. My outlets are connected, and when I init the object from initWithFrame:
everything is in order.
我有一个自定义UIView
对象,nib
它定义了视图/子视图布局。我的插座已连接,当我初始化对象时,initWithFrame:
一切都井然有序。
The problem I'm having is when I'm using IB to embed the UIView
into another nib; the custom UIView
appears, but none of the subviews it contains appear - in fact their symbols all resolve to nil. I have a very minimal initWithCoder:
and awakeFromNib:
implementation (just does logging) and my understanding is that as the nib is deserialized the subviews should at least be initialized during the process?
我遇到的问题是当我使用 IB 将其UIView
嵌入另一个笔尖时;自定义UIView
出现,但它包含的子视图没有出现 - 事实上它们的符号都解析为 nil。我有一个非常小的initWithCoder:
和awakeFromNib:
实现(只是不记录),我的理解是,当笔尖反序列化的子视图至少应该在过程中初始化?
The only conclusion I'm coming to on my own is that one of two things is happening: either my outlet references are corrupt/bad and aren't working, or my understanding of load-from-nib process is faulty and I'm missing something.
我自己得出的唯一结论是发生了两件事之一:要么我的插座引用损坏/坏并且无法正常工作,要么我对从笔尖加载过程的理解是错误的,我遗漏了什么。
Thanks in advance!
提前致谢!
Edit: (Code posted for Nekto as requested... as you'll see, it does logging and thats it, heh.)
编辑:(根据要求为 Nekto 发布代码......正如您所见,它会记录日志,仅此而已,呵呵。)
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
NSLog(@"ThumbnailGridView.initWithCoder frame= %f, %f", self.frame.size.width, self.frame.size.height);
}
return self;
}
- (void)awakeFromNib
{
NSLog(@"ThumbnailGridView:awakeFromNib");
}
Edit 2: Nibs, controllers, subviews, etc.
编辑 2:笔尖、控制器、子视图等。
Nibs: I have a single nib containing a UIView. This UIView contains a single UIScrollView, which is filled with a grid of UIViews that are defined in another nib. (Note: this part works fine, as the fill is done programmatically and works with an initWithFrame: call.) The problem here is that the UIScrollView symbol is nil after initWithCoder: and awakeFromNib: are both called, so objects are just being added to nil and nothing happens. If the scrollview symbol was not nil, I'm sure this would work.
笔尖:我有一个包含 UIView 的笔尖。这个 UIView 包含一个 UIScrollView,它填充了在另一个 nib 中定义的 UIViews 网格。(注意:这部分工作正常,因为填充是以编程方式完成的,并与 initWithFrame: 调用一起工作。)这里的问题是 UIScrollView 符号在 initWithCoder: 和awakeFromNib: 都被调用之后为零,所以对象只是被添加到零,什么也没有发生。如果滚动视图符号不为零,我相信这会起作用。
Controllers: There are two controllers that utilize this, one is done with initWithFrame: and works perfectly, the other embeds it as a nib-based reference. (As mentioned elsewhere here, defining a UIView in IB, setting the custom class.) I stepped through the code, and that view -is- being initialized properly - only its subviews are "missing".
控制器:有两个控制器可以利用它,一个是用 initWithFrame: 完成的,并且工作得很好,另一个将它嵌入为基于笔尖的参考。(正如这里其他地方所提到的,在 IB 中定义一个 UIView,设置自定义类。)我逐步完成了代码,并且该视图 - 正在正确初始化 - 只有它的子视图“丢失”。
Does this help give a clearer picture of the situation at all?
这是否有助于更清楚地了解情况?
回答by Robin Summerhill
You may be misunderstanding how nib loading works. If you define a custom UIView and create a nib file to lay out its subviews you can't just add a UIView to another nib file, change the class name in IB to your custom class and expect the nib loading system to figure it out. You need to modify initWithCoder of your custom UIView class to programmatically load the nib that defines its subview layout. e.g.:
您可能误解了笔尖加载的工作原理。如果您定义自定义 UIView 并创建一个 nib 文件来布置其子视图,则不能仅将 UIView 添加到另一个 nib 文件中,将 IB 中的类名更改为您的自定义类,并期望 nib 加载系统找出来。您需要修改自定义 UIView 类的 initWithCoder 以编程方式加载定义其子视图布局的笔尖。例如:
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil];
[self addSubview:self.toplevelSubView];
}
return self;
}
Your custom view's nib file needs to have the 'File's owner' class set to your custom view class and you need to have an outlet in your custom class called 'toplevelSubView' connected to a view in your custom view nib file that is acting as a container for all the subviews. Add additional outlets to your view class and connect up the subviews to 'File's owner' (your custom UIView).
您的自定义视图的 nib 文件需要将“文件的所有者”类设置为您的自定义视图类,并且您需要在您的自定义类中有一个名为“toplevelSubView”的插座连接到您的自定义视图 nib 文件中的视图,该视图充当所有子视图的容器。将额外的插座添加到您的视图类并将子视图连接到“文件的所有者”(您的自定义 UIView)。
Alternatively, just create your custom view programmatically and bypass IB.
或者,只需以编程方式创建自定义视图并绕过 IB。
回答by Robin Summerhill
Check that you are calling the 'super' implementation of initWithCoder: and awakeFromNib in each of your overridden methods i.e.
检查您是否在每个重写的方法中调用了 initWithCoder: 和awakeFromNib 的“超级”实现,即
- (id)initWithCoder:(NSCoder *)decoder {
if ((self = [super initWithCoder:decoder])) {
...your init code...
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
...your init code...
}