从nib加载自定义UIView,nib中包含的所有子视图都是nil?

str*_*hlr 31 iphone interface-builder uiview nib ios

我有一个自定义UIView对象,nib用于定义视图/子视图布局.我的插座是连接的,当我从initWithFrame:一切启动对象时,它是有序的.

我遇到的问题是当我使用IB将其UIView嵌入另一个笔尖时; 自定义UIView出现,但它包含的子视图都没有出现 - 实际上它们的符号都解析为nil.我有一个非常小的initWithCoder:awakeFromNib:实现(只是做记录),我的理解是,当笔尖反序列化的子视图至少应该在过程中初始化?

我自己得出的唯一结论就是两件事之一正在发生:我的插座引用是坏的/坏的并且不起作用,或者我对从笔尖加载过程的理解是错误的我是遗漏了什么.

提前致谢!

编辑:(根据要求为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");
}
Run Code Online (Sandbox Code Playgroud)

编辑2:笔尖,控制器,子视图等

Nibs:我有一个包含UIView的笔尖.这个UIView包含一个UIScrollView,它充满了另一个nib中定义的UIViews网格.(注意:这部分工作正常,因为填充是以编程方式完成的,并且与initWithFrame:call一起工作.)这里的问题是在initWithCoder之后UIScrollView符号是nil:并且awakeFromNib:都被调用,因此对象只是被添加到没有,没有任何反应.如果scrollview符号不是nil,我相信这会有效.

控制器:有两个控制器使用它,一个用initWithFrame完成:并且工作完美,另一个将它嵌入基于nib的引用.(如此处其他地方所述,在IB中定义UIView,设置自定义类.)我逐步完成了代码,并且该视图正在被正确初始化 - 只有它的子视图"缺失".

这有助于更清楚地了解情况吗?

Rob*_*ill 51

您可能误解了笔尖加载的工作原理.如果你定义一个自定义UIView并创建一个nib文件来布局它的子视图,你不能只是将UIView添加到另一个nib文件,将IB中的类名更改为你的自定义类,并期望nib加载系统找出它.您需要修改自定义UIView类的initWithCoder,以编程方式加载定义其子视图布局的nib.例如:

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil];
        [self addSubview:self.toplevelSubView];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

您的自定义视图的nib文件需要将"文件所有者"类设置为自定义视图类,并且您需要在自定义视图中将名为"toplevelSubView"的自定义类连接到自定义视图nib文件中的视图.所有子视图的容器.在视图类中添加其他插座,并将子视图连接到"文件所有者"(您的自定义UIView).

或者,只需以编程方式创建自定义视图并绕过IB.

  • [initWithCoder-> loadNibNamed让我进入无限循环](http://stackoverflow.com/questions/11450258/infinite-loop-when-overriding-initwithcoder) (15认同)

Rob*_*ill 5

检查你是否正在调用initWithCoder的'super'实现:并在每个被覆盖的方法中调用awakeFromNib,即

- (id)initWithCoder:(NSCoder *)decoder {
    if ((self = [super initWithCoder:decoder])) {
      ...your init code...
    }
    return self;
}

- (void)awakeFromNib {
     [super awakeFromNib];
     ...your init code...
}
Run Code Online (Sandbox Code Playgroud)