2013-10-14 9 views
9

最新のSDKを使用してiOS 5+アプリを開発しています。EXC_BAD_ACCESS(カスタムXIBでのカスタムUIView)

カスタムXIBを使用してカスタムUIView(TopMenuView)を作成しました。 Interface Builderでは、このXIBでUIViewクラスをTopMenuViewに変更しました。私はFile's Ownerを設定していません。

私が持っている TopMenuView.mオン

にInterface Builderを使用して
- (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; 
} 

私はUIViewControllerUIViewを追加し、TopMenuViewにこのUIViewクラスを変更しました。

しかし、私はアプリを実行したとき、私は、このログメッセージ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を追加していますが、メインビューはどこですか?ファイルの所有者に対してビューを宣言していません。 1つのビューをファイルの所有者に付ける必要があります。 – KDeogharkar

答えて

3

これを使用する一部のコントローラでは、おそらくTopMenuViewを使用したいを呼び出しています私はそれをどのようにしたのですか:

//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カスタムクラスがCustomNavigationViewであるUIViewサブクラスです。

これは私のために働く。

+0

素晴らしい作品! initWithCoderオーバーライド – Jesse

1

TopMenuViewが作成されるたびにあなたの- (id)initWithCoder:(NSCoder *)aDecoderが呼び出されますあなたのxibをロードしてください。

したがって、あなたが再帰的にあなたのinitWithCoder:


コメントすべてのあなたの方法- (id)initWithCoder:(NSCoder *)aDecoder

、あなたは以下のコード

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

はい、私はそれを知っています。どうすれば修正できますか? – VansFannel

9

再帰的にinitWithCoderを呼び出しているため、無限ループに陥っている可能性が最も高いです。 1つの回避策は、サブクラスに最初にサブビューがあるかどうかを確認することです。

-(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をxibファイルのルートビューからコードに変換することが必要でした。また、xibのFile's Ownerをカスタムクラスに設定していることを確認してください。

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これは詳細で正確な答えの1つです。 – Singh

+2

また、カスタムクラスがCocoapods依存関係のような別のプロジェクトのものである場合は、(カスタムクラスのすぐ下に)Moduleフィールドにも入力する必要があります。 – judepereira

関連する問題