使用自定义XIB的自定义UIView的EXC_BAD_ACCESS
我正在开发一个iOS 5+应用程序与最新的SDK。
我用自定义的XIB创build了一个自定义的UIView( TopMenuView
)。 在界面生成器我已经改变,在这个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; }
使用界面生成器我已经添加了一个UIView
到UIViewController
,并将此UIView
类更改为TopMenuView
。
但是,当我运行的应用程序,我得到这个日志消息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];
这是我做到的:
//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。
这对我有用。
它调用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 }
你很可能进入一个无限循环,因为你是recursion调用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; }
你的- (id)initWithCoder:(NSCoder *)aDecoder
被调用,只要通过加载你的xib创buildTopMenuView。
因此,你recursion地调用你的initWithCoder:
注释你所有的方法- (id)initWithCoder:(NSCoder *)aDecoder
以及您想在某些控制器中使用TopMenuView
位置,请使用下面的代码
NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; UIView *nv = [topMenuView objectAtIndex:0];
我得到同样的错误,直到我redid如何从故事板加载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 } }
我设置这个项目的完整答案就在这里 。