2010-02-17 23 views
24

Estoy intentando deducir de la documentación de sketchy de Apple qué método es el mejor lugar para inicializar y agregar mis controles de Vistas a la vista del controlador.¿Añado programáticamente SubViews en ViewDidAppear, ViewDidLoad, ViewWillAppear, el constructor?

Con winforms Es bastante sencillo, ya que siempre están inicializadas dentro InitializeDesigner, llamado en el constructor. Estoy intentando igualar la confiabilidad de este patrón si es posible.

Estoy trabajando con UIViewControllers y UITableViewControllers dentro de un UINavigationController la mayor parte del tiempo - si esto lo afecta a todos.

He aquí un ejemplo:

public MyController() 
{ 
    // Here? 
    AddViews(); 
} 

public override ViewDidLoad() 
{ 
    base.ViewDidLoad(); 

    // Or is should it be here? 
    AddViews(); 
} 

public override ViewWillAppear(bool) 
{ 
    base.ViewWillAppear(animated); 

    // Here? 
    AddViews(); 
} 

public override ViewDidAppear(bool animated) 
{ 
    base.ViewDidLoad(animated); 

    // Or maybe here? 
    AddViews(); 
} 

void AddViews() 
{ 
    UILabel label = new UILabel(); 
    label.Text = "Test"; 
    label.Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(label); 

    UIWebView webview = new UIWebView(); 
    webview .Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(webview); 
} 

puedo obtener resultados mixtos con algunas UIControls cuando los agrego a la vista en diferentes lugares. Retraso visual a veces, otras veces la vista web está oculta en alguna parte.

¿Hay una regla general a seguir para agregarlos?

+2

Vea también: http://stackoverflow.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload –

Respuesta

70

En general, esto es lo que hago:

  • viewDidLoad - Cada vez que estoy añadiendo controles a una vista que debe aparecer junto a la vista, de inmediato, me puso en el viewDidLoad método. Básicamente, este método se invoca cada vez que la vista se carga en la memoria. Entonces, por ejemplo, si mi vista es un formulario con 3 etiquetas, agregaría las etiquetas aquí; la vista nunca existirá sin esas formas.

  • ViewWillAppear: uso ViewWillAppear generalmente solo para actualizar los datos en el formulario. Entonces, para el ejemplo anterior, usaría esto para cargar los datos de mi dominio en el formulario. Creación de UIViews es bastante caro, y se debe evitar tanto como sea posible hacerlo en el método viewWillAppear, Becuase cuando este se llama, significa que el iPhone ya está listo para mostrar al UIView para el usuario, y nada pesado que hacer aquí afectará el rendimiento de una manera muy visible (como las animaciones que se retrasan, etc.).

  • ViewDidAppear: Por último, yo uso el ViewDidAppear para empezar nuevos temas a las cosas que se necesitaría mucho tiempo para ejecutar, como por ejemplo hacer una llamada de servicio web para obtener datos adicionales de la forma anterior.Lo bueno es que, debido a que la vista ya existe y se muestra al usuario, puede mostrar un buen mensaje de "Espera" al usuario mientras obtiene los datos.

Existen otros trucos que puede utilizar, sin embargo. Digamos que quiere un UILabel para "volar" en el formulario después de que se cargue el formulario. En ese caso, agregaría la etiqueta al formulario en ViewDidLoad pero con un marco fuera del área de visualización, y luego en ViewDidAppear haría la animación para devolverla a la vista.

Espero que ayude.

+0

Gracias que ha aclarado mucho. No he podido agregar nada con el ejemplo LoadView de esta pregunta: http://stackoverflow.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload - do ¿alguna vez usaste este método? –

+1

Así que, básicamente, loadView es un método del UIViewController (utilice la piedra rosetta cuando intenta resolver estas cosas - http://tirania.org/tmp/rosetta.html). El marco llama automáticamente a este método en el controlador para indicarle que cree vistas, y la implementación predeterminada del UIViewController llama al ViewDidLoad. Aunque puede anular este método (y asegúrese de llamar al método base cuando lo haga), personalmente prefiero usar el viewWillLoad (llamado antes de loadView) y viewDidLoad (llamado justo después). –

+0

@eduardo, docs aconseja no llamar a super en loadView –

8

Hmm, los documentos de Apple parecen ser bastante claros, en mi humilde opinión.

Si crea su propio punto de vista de la raíz (la vista raíz de la jerarquía de vistas de este controlador en particular) mediante programación, debe crearlo en -loadView sin llamar super y establezca la propiedad view cuando haya terminado. Si su vista se carga desde una punta, no debe tocar -loadView.

Agregue subvistas personalizadas a la vista del controlador de vista o modifíquelas en -viewDidLoad. La práctica recomendada es crear su UILabel y UIWebView en -viewDidLoad y liberarlos en -viewDidUnload, estableciendo sus referencias a nil si necesita mantenerlos en ivars.

Nota: -viewDidUnload está obsoleto en iOS 6 y ya no se llama más, porque UIViewController ya no purga su vista bajo la presión de la memoria.

+0

Gracias perdí ese método. Sin embargo, todavía siento que los métodos que enumeré brindan información muy limitada sobre cuándo usarlos. Incluso en loadView todo lo que se dice es * 'Si desea realizar una inicialización adicional de sus vistas, hágalo en el método viewDidLoad' * - ¿cuándo necesitaría este método? –

+0

loadView es el método que carga la jerarquía de vista desde NIB o simplemente crea una UIView vacía si no hay NIB para cargar. Es posible que desee una vista personalizada en lugar de ella, en cuyo caso anula loadView. UITableViewController, por ejemplo, anula este método para crear una UITableView. A menudo me encuentro haciendo lo mismo con mis propias subclases de UIView. – Costique

+0

viewDidUnload está en desuso –

2

viewDidLoad se refiere a 'MEMORY', y viewWillAppear/viewDidAppear al 'APARIENCIA'. La vista de un controlador de vista (que es una vista de raíz de las vistas de su controlador de vista) puede aparecer/desaparecer numerosas veces, incluso si la vista del controlador ya está en la memoria.

(Cuando me refiero a la vista de raíz, también me refiero a sus subvistas, porque la vista de raíz hace referencia a sus secundarios (subvistas), pero desde la perspectiva de un controlador de vista, normalmente solo conoce la vista de raíz. las subvistas pueden ocurrir normalmente a través de las salidas del controlador de visualización.)

La vista de la raíz en sí PUEDE ser eliminada de la memoria cuando hay una advertencia de memoria. El controlador de vista determinará cuándo es el mejor momento para eliminarlos de la memoria.

Por lo tanto, normalmente debería agregar las subvistas en viewDidLoad, porque agregar subvistas significa sumarlas a la memoria. PERO no si usted crea todas sus vistas programáticamente (no desde un archivo semilla). Si ese es el caso, entonces debe anular el método loadView y crear una vista de raíz y agregar subvistas, por lo que en este caso puede omitir viewDidLoad para agregar subvistas.

Cuestiones relacionadas