2013-10-14 79 views
9

我正在开发iOS 5+应用程序与最新的SDK。EXC_BAD_ACCESS自定义UIView与自定义XIB

我用自定义的XIB创建了一个自定义的UIView(TopMenuView)。在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我添加了一个UIViewUIViewController和改变了这种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]; 
+0

您将nv添加为子视图,但您的主视图在哪里?您没有向文件所有者声明任何视图。您必须将一个视图添加到文件的所有者。 – KDeogharkar

回答

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。

这适用于我。

+0

非常棒!你可以删除initWithCoder覆盖 – Jesse

1

每当创建TopMenuView- (id)initWithCoder:(NSCoder *)aDecoder被称为通过加载你的xib。

因此你递归调用您的initWithCoder:


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

,并要在其中可能使用TopMenuView在某些控制器使用下面的代码

NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; 
UIView *nv = [topMenuView objectAtIndex:0]; 
+0

是的,我知道。我该如何解决它? – VansFannel

9

你最有可能进入一个无限循环,因为你递归调用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; 
} 
0

我得到了同样的错误,直到我重做我怎么装从故事板的厦门国际银行文件。基本上它涉及使从XIB文件的根视图的代码的@IBOutlet。另外,请确保您设置的厦门国际银行的文件的所有者到您的自定义类。

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 
    } 
} 

设置此项目的完整答案是here

30

的原因它调用的initWithCoder这么多次是由于错误的类设置你的.xib文件。

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

enter image description here

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

enter image description here

现在,您可以在您的自定义班级中(斯威夫特)使用这一切:

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 
} 
+1

这真的解决了这个问题。只是觉得Xcode应该为这些'自定义类“配置提供更好的警告。 – RandyTek

+1

@JYeh这是一个详细而准确的答案。 – Singh

+2

另请注意,如果您的自定义类来自另一个项目,例如Cocoapods依赖项,那么您还需要填写Module字段(位于自定义类的下方)。 – judepereira