que life container iphone cocoa-touch ios uiview uiviewcontroller

iphone - life - viewcontroller swift



¿Estoy abusando de UIViewController Subclassing? (1)

Respuesta a la pregunta del título: Sí.

Entonces, básicamente, o he estado completamente equivocado, o estoy en una loca búsqueda.

Parece que has estado completamente equivocado. El término "vista" tiene algunos significados diferentes pero relacionados:

  • Una vista es, por supuesto, cualquier objeto que sea una instancia de UIView o una subclase de UIView.
  • En el contexto de MVC, "vista" se usa colectivamente, y hablamos de que esto o aquello sea "la responsabilidad de la vista" aunque "la vista" sea realmente un grupo de objetos.
  • Cuando se habla de un controlador de vista, la "vista" que administra el controlador es la instancia de UIView a la que apunta la vista del controlador y la jerarquía de subvistas que contiene.

Parece que su malentendido está en este último punto. Un controlador de vista debe administrar una sola "pantalla" de contenido. Si está utilizando un objeto de controlador de vista única para administrar más de una jerarquía de vistas, o si está usando varios controladores de vista para administrar diferentes partes de la misma jerarquía de vistas, está usando UIViewController de una manera que nunca fue intencional y lo que es probable que conduzca a problemas.

Los métodos que mencionó (-viewDidLoad, -viewWillAppear, etc.) están destinados a decirle al controlador de vista que su jerarquía de vista acaba de cargarse, está a punto de mostrarse, y así sucesivamente. Realmente no están destinados a referirse a una subvista individual, y sería inusual que a un controlador de vista se le deba dar esa información para subvistas individuales. Si se cargó la jerarquía de vistas, entonces el controlador de la vista sabe que todo en esa jerarquía se cargó.

Parece que estás interpretando estos métodos como métodos delegados, pero no lo son. Un delegado es un objeto separado que permite la personalización del delegador sin la necesidad de subclases. -viewDidLoad y -viewWillAppear son dos ejemplos de reemplazos de puntos para UIViewController, una clase que está destinada para la creación de subclases. El objeto controlador de vista llama a estos métodos para dar a las subclases la oportunidad de realizar alguna acción en un punto interesante del ciclo de vida del controlador.

Si no se puede contar con las subclases de UIViewController para llamar a viewWillAppear, ¿por qué no llamar a ese método manualmente y terminar con él?

Eche un vistazo a UIViewController y verá que la mayor parte de la funcionalidad proporcionada tiene que ver con mostrar la vista (es decir, la jerarquía de vista) en la pantalla, o con la integración del controlador con controladores de vista de "contenedor" como UINavigationController y UITabBarController. Nada de eso es útil para los objetos que no administran toda la pantalla llena de contenido.

A veces sucede que un grupo de vistas se replicará en varias pantallas, y en algunos de esos casos es útil administrar esas vistas con un objeto que está separado del controlador de vista en sí. Puedo ver cómo te sentirías tentado de usar UIViewController debido a its -viewDidLoad y métodos similares, pero esos son realmente solo una pequeña parte de lo que hace UIViewController. ¿Qué significa llamar a -presentModalViewController: en uno de esos objetos? ¿O para acceder a sus propiedades de navigationController o parentViewController ?

Si realmente desea administrar las subvistas de la jerarquía de vistas de su controlador de vista usando esos métodos, cree una subclase de NSObject que tenga métodos -viewDid [Cargar | Descargar | Aparecer | Desaparecer] y -visualizará [Aparecerá | Desaparecerá]. Puede crear esa clase una sola vez y luego subclasificarla tantas veces como lo necesite, y ninguna de sus clases de "subcontrolador" tendrá todas las cosas de gestión de controladores adicionales e innecesarias que se incluyen con UIViewController.

Edición: quiero agregar un puntero aquí a la Guía de programación de Apple View Controller para iOS , que brinda una gran cantidad de soporte para lo que he descrito anteriormente. Aquí hay un pasaje relevante de la subsección titulada "Controladores de vista Gestionar una jerarquía de vista":

Los controladores de vista están asociados directamente con un solo objeto de vista, pero ese objeto a menudo es solo la vista raíz de una jerarquía de vista mucho más amplia que también es administrada por el controlador de vista. El controlador de vista actúa como el agente coordinador central para la jerarquía de vistas, manejando los intercambios entre sus vistas y cualquier controlador relevante u objetos de datos. Un solo controlador de vista generalmente administra las vistas asociadas con el contenido de una sola pantalla, aunque en las aplicaciones de iPad este no siempre sea el caso.

Ver la Guía de programación del controlador es una lectura obligatoria para cualquier persona que esté pensando en escribir una aplicación de iOS. Vale la pena revisar si no lo has leído en mucho tiempo (o nunca).

Actualización: comenzando con iOS 5, ahora es posible definir sus propios controladores de vista de contenedor, es decir, ver controladores que administran otros controladores de vista y potencialmente mostrar las vistas de múltiples controladores de vista al mismo tiempo. Puede leer más sobre esto en la guía vinculada anteriormente en la sección titulada Cómo crear controles de vista de contenedor personalizados . Nada de esto realmente cambia los puntos esenciales anteriores: un controlador de vista única aún debe administrar una jerarquía de vistas, y métodos como -viewDidLoad todavía se refieren a todo el gráfico de vista en lugar de a subvistas individuales. El consejo de que un controlador de vista administra una "pantalla completa" de contenido ya no es completamente preciso, así como UISplitViewController ha mostrado contenido de dos controladores de vista simultáneamente desde la introducción del iPad, sus propios contenedores ahora pueden mostrar las vistas de múltiples Controladores de vista infantil. Escribir un controlador de vista de contenedor es un tema algo avanzado: usted debe estar muy familiarizado con el uso de los controladores de vista en general y la forma en que funcionan los controladores de vista de contenedor antes de intentar crear el suyo propio.

Al tratar de descubrir por qué no se llamaba a ViewWillAppear en mi aplicación, me di cuenta de lo que podría ser un gran malentendido sobre el uso previsto de las subclases UIViewController.

De acuerdo con la siguiente vista posterior, ¡ WillAppear no se ejecuta cuando se utiliza addSubView! y el enlace a esta entrada del blog: http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/ Las subclases de UIViewController solo deberían ocurrir en situaciones muy específicas. En particular, cuando se agrega directamente a UIWindow u otros controladores personalizados creados por Apple, como UINavigationControllers.

Ciertamente soy culpable de agregar las vistas de las subclases UIViewController a las vistas de otras subclases UIViewController.

De hecho, pensé que esto era más o menos la idea general de la implementación de MVC por parte de Apple ... Un VC general, con otros VCs por debajo, todos felizmente recibiendo sus métodos de delegado.

Si hay muchas vistas (que por definición necesitan control) que entran y salen en una aplicación, y muchos screenfulls, en el modelo descrito en esa publicación, cada screenfull debe tener una Subclase maestra VC, con todas las subvistas controladas en lugar de controladores personalizados (que suceden a las vistas de control) que son subclases de NSObject simple.

En este caso, UIViewControllers solo debe estar directamente en Window o UINavigationController, UITabBarController, etc.

¿Tiene la garantía de obtener los métodos de Delegado UIVC llamados en ese caso? ¿En qué se diferencia esto de llamar a los métodos de delegado manualmente cuando la vista de un controlador de visualización es una subvista de otro VC?

Sinceramente, esto parece una tremenda pérdida de tiempo. Implementaciones personalizadas de ViewDidLoad, viewDidLoad, viewDidUnload, viewWillAppear, viewWillDisappear para no mencionar cosas tan simples como propiedades como, por ejemplo, "ver" ...

Entonces, básicamente, o he estado completamente equivocado, o estoy en una loca búsqueda. Si no se puede contar con las subclases de UIViewController para llamar a viewWillAppear, ¿por qué no llamar a ese método manualmente y terminar con él?

¿Por qué replicar toda la funcionalidad percibida de UIViewController?