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];
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.
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:
et assurez-vous que la classe sur la vue racine est L'uivi par défaut:
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
}
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;
}
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];
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 .