2010-01-22 14 views
11

Tengo un UIViewController con su propio .xib, y quiero usar un UISegmentedControl para mostrar información diferente en la mitad inferior de la pantalla. Creé un UIView en .xib del contenedor y lo conecté a una propiedad de UIView llamada detailView en el UIViewController del contenedor.Cargando .xibs en un UIView

Luego creé tres archivos .xib en IB, uno para la vista que cada segmento necesita mostrar en el área detailView.

Ahora estoy atascado porque no sé cómo cargar y descargar el archivo .xib apropiado en el área detailView. Aquí es donde estoy:

- (void)segmentValueChanged:(id)sender { 
    switch ([sender selectedSegmentIndex]) { 
     case 0: 
      // Unload whatever is in the detailView UIView and 
      // Load the AddressView.xib file into it 
      break; 
     case 1: 
      // Unload whatever is in the detailView UIView and 
      // Load the ContactsView.xib file into it 
      break; 
     case 2: 
      // Unload whatever is in the detailView UIView and 
      // Load the NotesView.xib file into it 
      break; 
     default: 
      break; 
    } 
} 

Entonces, ¿cómo tengo que llenar los espacios en blanco y descargar/cargar la DetailView UIView correctamente?

Gracias!

--UPDATE--

El código en viewDidLoad es ahora: - (void) {viewDidLoad [súper viewDidLoad];

// Set the default detailView to be address since the default selectedSegmentIndex is 0. 
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil]; 
    // assuming the view is the only top-level object in the nib file (besides File's Owner and First Responder) 
    UIView *nibView = [nibObjects objectAtIndex:0]; 
    self.detailView = nibView; 

    self.detailContainerView.autoresizesSubviews = YES; 
    [self.detailContainerView addSubview:self.detailView]; 

    NSLog(@"self.view is %@", self.view); 
    NSLog(@"self.detailContainerView is %@",self.detailContainerView); 
    NSLog(@"self.detailView is %@", self.detailView); 
} 

Y los mensajes de depuración son:

self.view is UIView: 0x3a24d80; frame = (0 0; 320 460); autoresize = RM+BM; layer = CALayer: 0x3a35190 
self.detailContainerView is UIView: 0x3a1aea0; frame = (20 57; 280 339); autoresize = W+H; layer = CALayer: 0x3a36b80 
self.detailView is UIView: 0x3a24d80; frame = (0 0; 320 460); autoresize = RM+BM; layer = CALayer: 0x3a35190 

Gracias!

Respuesta

24

Utilice NSBundle's loadNibNamed:owner:options:. Devuelve una matriz de todos los objetos de nivel superior en el archivo NIB, que luego puede asignar a sus ivars. Si necesita distinguir entre múltiples objetos en la matriz, déle a cada una una etiqueta única en IB.

Prueba esto:

case 0: 
    [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil]; 
    break; 
... 

Si ha especificado el controlador de vista como el propietario del archivo de AddressView.xib en Interface Builder, y ha conectado la vista en el XI ter del enchufe DetailView del controlador de vista, la conexión entre la vista y self.detailView debe estar en su lugar después de la llamada a loadNibNamed (porque ha especificado self como propietario).

Si eso no funciona, pruebe algo como esto:

case 0: 
    NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"AddressView" owner:self options:nil]; 
    // assuming the view is the only top-level object in the nib file (besides File's Owner and First Responder) 
    UIView *nibView = [nibObjects objectAtIndex:0]; 
    self.detailView = nibView; 
    break; 
... 

hacer lo mismo para todos los casos en la sentencia switch. Si ha declarado detailView como @property (retain), la asignación self.detailView = ... se encargará de liberar las vistas cargadas anteriormente. No es necesario descargar específicamente el contenido de NIB.

+0

No estoy muy seguro de cómo armar eso. ¿Debo llamar a 'loadNibNamed: owner: options:' para cada uno de los .xib?¿Sería posible ver algún código aproximado para tener una idea de cómo hacer esto? ¡Muchas gracias! –

+0

He agregado un código a mi respuesta. –

+0

Ole, gracias por el gran código! El único problema al que me estoy enfrentando es que cuando llamo a -loadNibNamed: owner: options, el NIB se superpone sobre la vista completa en la que se supone que está dentro. Parece que 'self.detailView = nibView;' no cambia el tamaño del NIB cargado para que quepa dentro de la vista detallada que se configuró en IB. Alguna idea aqui? ¡Gracias! –

1

Básicamente es necesario utilizar initWithNibName de UIViewController a hacer lo que quiera:

UIViewController *aViewController = [[UIViewController alloc] initWithNibName:@"AddressView" bundle:nil]; 
[self.detailView addSubview:aViewController.view]; 
[aViewController release]; // release the VC 

En su xib AddressView, conjunto de clases propietario del archivo a UIViewController. La clase de la vista debe ser la clase personalizada AddressView.

De esta manera puede posicionar y dimensionar la subvista utilizando el archivo xib principal. Luego use el xib de la subvista para diseñar los controles.