2009-08-11 6 views
19

Ich arbeite an einer iPhone App und bekomme (Null) Verweise auf IBOutlet Felder in meinem Controller. Ich habe eine UIViewController-Unterklasse, die in meiner XIB als Besitzer der Datei festgelegt ist. Ich habe eine Reihe von UI-Elementen, die in den Controller verdrahtet sind. Nach dem Laden von NIB und dem Versuch, Eigenschaften für diese UI-Elemente festzulegen, stelle ich fest, dass sie (null) sind. Um zu klären, einige Code:IBOutlet Instanzen sind (null) nach dem Laden von 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 als Datei Besitzer für ExpandSearchPage.xib gesetzt. ExpandSearchPage.xibs UITextView ist mit der completeMessageView verbunden.

Als ich

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

[searchExpanderPage checkTextField]; 

nenne das Ergebnis ist

"text field: (null)" 

Antwort

49

ich die Frage erraten fragen nach über eine Stunde auf das Problem der Suche führte mich um es herauszufinden:

Ich habe gerade meinen Code in das Textfeld nach dem Anzeigen der Ansicht zu überprüfen ... jetzt alles instanziiert .

Stellen Sie sich vor, dass die UI-Elemente nicht instanziiert werden, bis Sie sie anzeigen!

+0

Ein weiterer Punkt von Interesse, die mich gefangen. Wenn Sie einen View-Controller modal mit 'presentViewController: animated: completion:' präsentieren, sind alle IBOutlets null bis die Ansicht erscheint (was Sie entdeckt haben). Sie müssen also auf sie über den Completion-Block zugreifen, der aufgerufen wird, wenn "viewDidAppear" für das Modal aufgerufen wird. – guptron

0

Achten Sie auf die Ansicht Eigenschaft Ihrer View-Controller (dh Datei-Besitzer in diesem Fall) zu der Ansicht in Ihrem xib verdrahtet ist. Da Ihr TextField mit ziemlicher Sicherheit eine Unteransicht davon ist, ist es wichtig, dass auch dies verdrahtet wird (und ich denke nicht, dass die Schreibspitze richtig geladen wird, ohne dass sie eingestellt wird).

3

Eine andere mögliche Ursache für einen Null-IBOutlet-Zeiger besteht darin, zu vergessen, die XIB-Datei in Interface Builder nach dem Erstellen der Ausgangsverbindung zu speichern.

+1

Ich glaube, das war ein Problem in den früheren Versionen von XCode -% -R hat nicht automatisch gespeichert. Jetzt tut es das. Immer noch +1 für etwas, auf das man achten sollte. – mobibob

4

Dies ist die Lösung.

Die IBOutlets können erst verwendet werden, wenn der View Controller geladen wurde.

Wenn Sie beispielsweise eine UILabels-Texteigenschaft festlegen möchten, müssen Sie zuerst einen NSString auf Ihrem Controller festlegen und dann die text -Eigenschaft des Labels wie in viewDidLoad festlegen.

Also in Ihrem firstViewController.m: (es für Storyboards, aber gleiche Idee gilt)

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

Dann in der .h Ihren secondViewController:

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

Dann setzten wir den Text Eigenschaft auf dem UILabel, in der ViewDidLoad von secondViewController.m. Zu diesem Zeitpunkt wurde das IBOutlet erstellt und kann jetzt verwendet werden.Diese

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

ist, wie ich es tun:

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