6

En la publicación Using initWithNibName changes absolutely nothing, muestra dos usos de la misma definición de View Nib, en el primer caso, simplemente llama a alloc/init y el segundo, especifica initWithNibName.¿Cuándo debo llamar - [UIViewController initWithNibName: bundle:]?

Por lo tanto, si bien esto siempre funciona:

MyViewController *vctrlr = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

Los siguientes obras para todos los controladores de Vista que he heredado, pero no la mía!

TheirViewController *vctrlr = [[TheirViewController alloc] init]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

nuevo en la programación iOS, heredé algo de código. Todas las vistas de los Controladores de Vista están definidas en IB, pero hubo una asignación/creación incoherente de esos controladores de vista. Creé un nuevo Controlador de Vista y XIB, pero no funciona a menos que use initWithNibName (se cuelga cuando presiono el controlador de vista en el Controlador Nav). No puedo decir cómo mi controlador de vista es diferente a los demás ... ¿alguna pista? Pude borrar el uso de initNibName para todos los otros controladores de vista en la aplicación excepto la mía.

+0

En general es bueno para especificar el nombre de la SEMILLA ya que en realidad abstrae la vista desde la viewcontroller. Por ejemplo, si tiene un controlador que tiene vistas ligeramente diferentes en función de algunas condiciones, puede simplemente cargar en distintas puntas como sus vistas. – Rexeisen

+0

¿Ha implementado el método 'loadView' en' vctrlr'? –

+0

'loadViews' no se implementan en ningún caso. – wrlee

Respuesta

1

Puede pasar cualquier nombre de cadena a initWithNibName:. No solo está restringido a llamar al initWithNibName:@"MyClassName" cuando su clase se llama MyClassName. Podría ser initWithNibName:@"MyClassNameAlternateLayout".

Esto se vuelve útil si necesita cargar una punta diferente dependiendo de lo que la aplicación necesite hacer. Mientras trato de tener un controlador de punta por vista por categoría de dispositivo (iPhone o iPad) siempre que sea posible para simplificar el desarrollo y el mantenimiento, podría entender si un desarrollador quisiera proporcionar un diseño diferente o una funcionalidad diferente a veces.

Otro punto importante es que initWithNibName:bundle: es el inicializador designado para UIViewController. Cuando llama al -[[UIViewController alloc] init], se llama initWithNibName:bundle: entre bastidores. Puede verificar esto con un punto de corte simbólico. En otras palabras, si simplemente desea el comportamiento predeterminado, se espera que pueda llamar al -[[UIViewController alloc] init] y se llamará implícitamente al inicializador designado.

Si, sin embargo, llama al -[[UIViewController alloc] init] y no obtiene el comportamiento esperado, es probable que su subclase UIViewController haya implementado - (id)init incorrectamente. La aplicación debe ser similar a uno de estos dos ejemplos:

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // custom initialization 
    } 
    return self; 
} 

o

- (id)init 
{ 
    NSString *aNibName = @"WhateverYouWant"; 
    NSBundle *aBundle = [NSBundle mainBundle]; // or whatever bundle you want 
    self = [self initWithNibName:aNibName bundle:aBundle]; 
    if (self) { 
     // custom initialization 
    } 
    return self; 
} 
+1

+1: También me gustaría agregar que * puedes usar el mismo xib * para diferentes 'UIViewController's. Por ejemplo, puede tener un padre 'UIViewController' que tenga subclases que tengan una funcionalidad similar (pero no la misma) utilizando el mismo conjunto' IBOutlet's. En este caso, necesitaría usar el método 'initWithNibName: bundle:' para especificar el nombre del archivo padre 'xib'. –

0
If you want to work following code: 

MyViewController *vctrlr = [[MyViewController alloc] inil]; 
[self.navigationController pushViewController:vctrlr animated:YES]; 

Then you should implement following both methods in MyViewController: 

- (id)init 
{ 
    self = [super initWithNibName:@"MyViewController" bundle:nil]; 
    if (self != nil) 
    { 
     // Do initialization if needed 
    } 
    return self; 
} 
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{ 
    NSAssert(NO, @"Init with nib"); 
    return nil; 
} 
+0

Usó el método incorrecto porque el uso del nombre de archivo nib al crear el objeto de viewcontroller desde el exterior, rompe la encapsulación. –

Cuestiones relacionadas