覆盖initWithCoder时的无限循环

Jon*_*mvi 13 objective-c interface-builder storyboard ios ios5

我有UIViewController一些控制器和一些视图.其中两个视图(Grid Cell)是其他nib.我有从Grid Cells到File的Owner的插座,但它们没有自动加载.

所以我试图覆盖GridCell.m's initWithCoder.这开始了一个无限循环.

我知道可以覆盖initWithFrame并添加代码中的子视图,但这不是我想要的.我希望能够在Interface Builder中移动视图并让Xcode使用正确的框架初始化视图.

我该如何实现这一目标?

编辑1

我正试着在亚历山大的帮助下工作.这就是我现在设置的方法:MainView将UIView的Custom类设置为GridCell.它在MainView/File的所有者中有一个插座.

图1

从GridCell.m中删除了所有init-code并为我的自定义类设置了一个插座

图2

图3

但MainView仍然不会显示GridCell.没有错误,只是一个孤独的,空的空间,红色开关应该是.我究竟做错了什么?

我非常接近于以编程方式执行此操作.我很想学习如何使用笔尖.

小智 43

加载nib会导致再次调用initWithCoder,因此如果子类当前没有任何子视图,您只想这样做.

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        if (self.subviews.count == 0) {
            UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil];
            UIView *subview = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
            subview.frame = self.bounds;
            [self addSubview:subview];
        }
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

  • 这可行,但它会在您的自定义视图下创建一个额外的"UIView". (2认同)

Ale*_*der 11

加载笔尖将导致相应的所有者

  -(id) initWithCoder:(NSCoder *) coder;  
Run Code Online (Sandbox Code Playgroud)

呼叫

因此你的方法是这样的:

self = [[[NSBundle mainBundle] loadNibNamed: @"GridCell"
owner: self
options: nil] objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)

将再次导致调用initWithCoder方法.那是因为你试图再次加载笔尖.如果你定义一个自定义UIView并创建一个nib文件来布局它的子视图,你不能只是将UIView添加到另一个nib文件,将IB中的类名更改为你的自定义类,并期望nib加载系统找出它.你能做的是以下几点:

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

编辑 好的,要回答您编辑的问题,我会做以下事情:

转到要包含自定义视图的nib文件,并使用它的nib文件进行布局.不要进入自定义视图(GridCell)本身,而是创建一个包含网格单元格的视图(例如gridCellContainer,但它应该是UIView)在自定义视图中自定义initWithFrame方法,就像在initWithCoder中一样:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"GridCell" owner:self options:nil];    
        self = [nib objectAtIndex:0];
        self.frame = frame;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

然后,在viewController中,它是要包含自定义视图的视图的fileOwner(带有gridCellContainer视图的视图),请在viewDidLoad中执行此操作,例如:

//...
GridCell *gridCell = [[GridCell alloc] initWithFrame:self.viewGridCellContainer.bounds];
[self.viewGridCellContainer addSubview:gridCell];
Run Code Online (Sandbox Code Playgroud)

现在eveything应该按照你的预期工作