EXC BAD ACCESS sur custom UIView avec custom XIB

je développe une application iOS 5+ avec le dernier SDK.

j'ai créé un uivi personnalisé ( TopMenuView ) avec un XIB personnalisé. Sur Interface Builder j'ai changé, sur ce XIB, la classe UIView en TopMenuView . Je n'ai pas mis de File's Owner .

Sur TopMenuView.m j'ai:

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

utilisant Interface Builder j'ai ajouté un UIView à un UIViewController et j'ai changé cette classe UIView en TopMenuView .

mais, quand j'exécute l'application, je reçois ce message de log 4251 fois: 2013-10-13 20:49:34.078 MyProject[470:c07] init with coder: 0

et puis, je reçois un EXC_BAD_ACCESS ici:

NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView"
                                                             owner:nil
                                                           options:nil];
13
demandé sur VansFannel 2013-10-14 11:11:00

5 réponses

C'est comme ça que je l'ai fait:

//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];    

ici CustomNavigationView est une sous-classe UIView avec la classe de propriétaire de fichiers UIView et la classe custom UIView avec CustomNavigationView.

ça me va.

2
répondu Geekoder 2013-10-14 07:26:45

la raison pour laquelle il appelle l'initWithCoder autant de fois est due à la mauvaise configuration de la classe dans votre .fichier xib.

assurez-vous que la classe personnalisée sur le propriétaire du fichier est votre classe uivi personnalisée:

enter image description here

et assurez-vous que la classe sur la vue racine est L'uivi par défaut:

enter image description here

et maintenant c'est tout ce dont vous avez besoin dans votre classe personnalisée (en 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
}
40
répondu JYeh 2016-03-10 17:05:32

vous êtes très probablement entrer dans une boucle infinie parce que vous appelez récursivement initWithCoder . Une solution consiste à vérifier si votre sous-classe A d'abord des sous-vues.

-(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;
}
9
répondu Sebyddd 2015-03-04 12:13:23

votre - (id)initWithCoder:(NSCoder *)aDecoder est appelé chaque fois que TopMenuView est créé en chargeant votre xib.

ainsi vous appelez récursivement votre initWithCoder:


Comment toute votre méthode - (id)initWithCoder:(NSCoder *)aDecoder

et où vous voulez utiliser TopMenuView probablement dans certains controller utiliser le code ci-dessous

NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil];
UIView *nv = [topMenuView objectAtIndex:0];
1
répondu Inder Kumar Rathore 2013-10-14 07:24:27

j'ai eu la même erreur jusqu'à ce que je redirige comment j'ai chargé le fichier xib à partir du storyboard. En gros, il s'agissait de faire un @IBOutlet à partir de la vue racine du fichier xib vers le code. Assurez-vous également que vous avez défini le propriétaire du fichier xib à votre classe personnalisée.

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

ma réponse complète pour la mise en place de ce projet est ici .

0
répondu Suragch 2017-05-23 11:54:24