2009-08-11 14 views
19

Estoy trabajando en una aplicación de iPhone y obtengo referencias (nulas) a los campos de IBOutlet en mi controlador. Tengo una subclase UIViewController que se establece como el propietario del archivo en mi XIB. Tengo un conjunto de elementos UI que están conectados al controlador. Después de cargar desde NIB e intentar establecer propiedades en esos elementos de la interfaz de usuario, descubro que son (nulos). Para aclarar, algo de código:Las instancias de IBOutlet son (nulas) después de cargar desde 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 se establece como el propietario del archivo de ExpandSearchPage.xib. La UITextView de ExpandSearchPage.xib está conectada a la vista de mensaje completa.

Cuando llamo

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

[searchExpanderPage checkTextField]; 

el resultado es

"text field: (null)" 

Respuesta

49

supongo que la pregunta después de ver el problema para más de una hora me llevó a averiguarlo:

Acabo de cambiar mi código para comprobar el cuadro de texto después de visualizar la vista ... ahora todo se crea una instancia .

Imagine que: los elementos de la interfaz de usuario no se crean instancias hasta que los visualice.

+0

Otro punto de interés que me atrapó. Al presentar un controlador de vista modalmente con 'presentViewController: animated: completion:', todas las IBOutlets serán nulas hasta que aparezca la vista (lo que descubriste). Por lo tanto, tendrá que acceder a ellos a través del bloque de finalización, que se llama cuando se invoca 'viewDidAppear' en el modal. – guptron

0

Asegúrese de que la ventana de propiedades del controlador de vista (propietario es decir del fichero en este caso) está cableado a la vista en su xib. Como tu campo de texto es casi seguro una sub-vista de eso, es importante que también lo conectes (y no creo que el plumín se cargue correctamente sin que esté configurado).

3

Otra posible causa de un puntero IBOutlet nulo es olvidarse de guardar el archivo xib en el Interface Builder después de crear la conexión de salida.

+1

Creo que fue un problema en las versiones anteriores de XCode -% -R no se guardó automáticamente. Ahora lo hace. Todavía +1 como algo para tener cuidado. – mobibob

4

Esta es la solución.

Las IBOutlets no están listas para usar hasta que el controlador de vista termine de cargarse.

Por ejemplo, si desea establecer una propiedad de texto UILabels, primero deberá establecer un NSString en su controlador y luego establecer la propiedad de texto de las etiquetas en algún lugar como viewDidLoad.

Así que en su firstViewController.m: (Esto es para guiones gráficos, pero misma idea se aplica)

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

Luego, en el .h de su secondViewController:

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

A continuación, establecemos el texto propiedad en UILabel, en viewDidLoad de secondViewController.m. En esta etapa, IBOutlet se ha creado y está listo para funcionar.

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

Esto es cómo lo hago:

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