23

我正在使用最新的 SDK 开发 iOS 5+ 应用程序。

我创建了一个TopMenuView带有自定义 XIB 的自定义 UIView ()。在 Interface Builder 上,我已在此 XIB 上将UIView类更改为TopMenuView. 我没有设置任何File's Owner.

TopMenuView.m有:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        NSLog(@"init with coder: %d", counter);
        counter++;
        // Add custom XIB
        NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView"
                                                             owner:nil
                                                           options:nil];
        UIView *nv = [topMenuView objectAtIndex:0];

        [self addSubview:nv];
    }

    return self;
}

使用 Interface Builder 我已将 a 添加UIView到 aUIViewController并将此类更改UIViewTopMenuView.

但是,当我运行应用程序时,我收到了 4251 次日志消息: 2013-10-13 20:49:34.078 MyProject[470:c07] init with coder: 0

然后,我在EXC_BAD_ACCESS这里得到一个:

NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView"
                                                             owner:nil
                                                           options:nil];
4

5 回答 5

68

它多次调用 initWithCoder 的原因是您的 .xib 文件中的类设置错误。

确保文件所有者上的自定义类是您的自定义 UIView 类:

在此处输入图像描述

并确保根视图上的类是默认的 UIView:

在此处输入图像描述

现在这就是您在自定义类中所需要的(在 Swift 中):

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    let view = NSBundle.mainBundle().loadNibNamed("TopMenuView", owner: self, options: nil)[0] as! UIView
    self.addSubview(view)
    view.frame = self.bounds
}
于 2016-03-10T17:05:32.677 回答
11

您很可能会进入无限循环,因为您正在递归调用initWithCoder. 一种解决方法是首先检查您的子类是否有任何子视图。

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        if (self.subviews.count == 0) {
            NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil];
            UIView *nv = [topMenuView objectAtIndex:0];
            [self addSubview:self.view];
        }
    }
    return self;
}
于 2015-03-04T12:13:23.563 回答
3

我是这样做的:

//Add Custom View to my main view of viewcontroller
self.customNavView = [[CustomNavigationView alloc] init];
self.customNavView = [[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationView" owner:self options:nil] objectAtIndex:0];
[self.customNavView setFrame:CGRectMake(0, 20, 320, 54)];
[self.view addSubview:self.customNavView];    

这里的CustomNavigationView是一个UIView子类,文件所有者类为UIView,UIView自定义类为CustomNavigationView。

这对我有用。

于 2013-10-14T07:26:45.360 回答
1

- (id)initWithCoder:(NSCoder *)aDecoder每当TopMenuView通过加载您的 xib 创建时都会调用您的。

因此,您递归地调用您的initWithCoder:


评论你所有的方法- (id)initWithCoder:(NSCoder *)aDecoder

并且您TopMenuView可能想在某些控制器中使用以下代码

NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil];
UIView *nv = [topMenuView objectAtIndex:0];
于 2013-10-14T07:17:28.170 回答
0

在我重新修改从情节提要加载 xib 文件的方式之前,我遇到了同样的错误。基本上它涉及从 xib 文件的根视图到代码创建一个@IBOutlet。还要确保将 xib 的文件所有者设置为自定义类。

import UIKit
class ResuableCustomView: UIView {

    @IBOutlet var view: UIView!
    @IBOutlet weak var label: UILabel!

    @IBAction func buttonTap(sender: UIButton) {
        label.text = "Hi"
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        NSBundle.mainBundle().loadNibNamed("ReusableCustomView", owner: self, options: nil)[0] as! UIView
        self.addSubview(view)
        view.frame = self.bounds
    }
}

我设置这个项目的完整答案在这里

于 2015-12-30T07:29:49.453 回答