2009-08-11 7 views
19

Je travaille sur une application iPhone et je reçois des références (null) aux champs IBOutlet dans mon contrôleur. J'ai une sous-classe UIViewController qui est définie en tant que propriétaire du fichier dans mon XIB. J'ai un ensemble d'éléments d'interface utilisateur qui sont câblés dans le contrôleur. Après le chargement de NIB et la tentative de définir des propriétés sur ces éléments d'interface utilisateur, je trouve qu'ils sont (null). Pour clarifier, un code:Les instances IBOutlet sont (NULL) après le chargement de NIB

ExpandSearchPageController.h:

@interface ExpandSearchPageController : UIViewController 
{ 
    IBOutlet UITextView * completeMessageView; 
} 

-(void)checkTextField; 

@property (nonatomic, retain) IBOutlet UITextView * completeMessageView; 

ExpandSearchPageController.m:

@implementation ExpandSearchPageController 

@synthesize completeMessageView; 

-(void)checkTextField 
{ 
    NSLog(@"text field: %@",completeMessageView); 
} 

ExpandSearchPageController est défini comme propriétaire pour ExpandSearchPage.xib du fichier. UITextView de ExpandSearchPage.xib est câblé à completeMessageView.

Quand j'appelle

ExpandSearchPageController * searchExpanderPage = [[ExpandSearchPageController alloc] initWithNibName:@"ExpandSearchPage" bundle:[NSBundle mainBundle]]; 

[searchExpanderPage checkTextField]; 

le résultat est

"text field: (null)" 

Répondre

49

Je suppose que poser la question après avoir examiné le problème pendant plus d'une heure m'a amené à le comprendre:

Je viens de modifier mon code pour vérifier la zone de texte après l'affichage de la vue ... maintenant tout est instancié . Imaginez que: les éléments de l'interface utilisateur ne sont pas instanciés jusqu'à ce que vous les affichiez!

+0

Un autre point d'intérêt qui m'a pris. Lorsque vous présentez un contrôleur de vue de manière modale avec 'presentViewController: animated: completion:', tous les IBOutlets seront nuls jusqu'à ce que la vue apparaisse (ce que vous avez découvert). Vous aurez donc besoin d'y accéder via le bloc d'achèvement, qui est appelé quand 'viewDidAppear' est appelé sur le modal. – guptron

0

Assurez-vous que la propriété vue de votre contrôleur de vue (propriétaire de par exemple fichier dans ce cas) est câblé à la vue dans votre xib. Comme votre textField est presque certainement une sous-vue de cela, il est important de le brancher aussi (et je ne pense pas que la plume se chargera correctement sans cela).

3

Une autre cause potentielle d'un pointeur IBOutlet nul est l'oubli de l'enregistrement du fichier xib dans Interface Builder après la création de la connexion de sortie.

+1

Je crois que c'était un problème dans les versions antérieures de XCode -% -R n'a pas enregistré automatiquement. Maintenant c'est le cas. Encore +1 comme quelque chose à surveiller. – mobibob

4

Ceci est la solution.

Les points de connexion IB ne sont pas prêts à être utilisés tant que le contrôleur de vue n'a pas terminé le chargement. Par exemple, si vous souhaitez définir une propriété de texte UILabels, vous devez d'abord définir une NSString sur votre contrôleur, puis définir la propriété text des libellés comme viewDidLoad.

Donc, dans votre firstViewController.m: (Ceci est pour storyboards, mais même idée s'applique)

- (void)buttonPress:(id)sender { 
    [self performSegueWithIdentifier:@"mySegue" sender:self]; 
} 

- (void)prepareForSegue(UIStoryboardSegue *)segue sender:(id)sender { 
    SecondViewController *secondViewController = [segue destinationViewController]; 
    secondViewController.stringForLabel = @"My Label String"; 
} 

Ensuite, dans le .h de votre secondViewController:

@property (strong, nonatomic) IBOutlet UILabel *label; 
@property (strong, nonatomic) NSString *stringForLabel; 

Ensuite, nous avons mis le texte propriété sur UILabel, dans viewDidLoad de secondViewController.m. A ce stade, l'IBOutlet a été créé et est prêt à fonctionner.

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.label.text = self.stringForLabel; 
} 
0

Voici comment je le fais:

//in your view controller 
-(void)setUp 
{ 
    [self.cardView layoutIfNeeded]; 
    LearnCardPlainText *cardNib = [[[UINib nibWithNibName:@"LearnCardPlainText" bundle:nil] instantiateWithOwner:self options:nil] objectAtIndex:0]; 
    cardNib.frame = self.cardView.frame; 
    [cardNib setUpWithPart:learnModel]; 
    [self.view addSubview:cardNib]; 
}