我正在使用最新的SDK开发iOS 5+应用程序。
我创建了一个带有自定义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我已将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];
答案 0 :(得分:52)
它多次调用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
}
答案 1 :(得分: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;
}
答案 2 :(得分:2)
我就这样做了:
//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。
这适合我。
答案 3 :(得分:1)
通过加载xib,只要创建- (id)initWithCoder:(NSCoder *)aDecoder
,就会调用TopMenuView
。
因此,您递归调用initWithCoder:
评论您的所有方法- (id)initWithCoder:(NSCoder *)aDecoder
以及您想在某些控制器中使用TopMenuView
的地方使用以下代码
NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil];
UIView *nv = [topMenuView objectAtIndex:0];
答案 4 :(得分: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
}
}
我设置此项目的完整答案是here。