2010-03-11 19 views
18

Estoy tratando de ajustar los controladores en Cocoa Touch. El problema principal es que me gustaría tener más de un controlador "en pantalla" a la vez: quiero tener una vista grande (con el controlador A) compuesta de vistas más pequeñas controladas por sus propios controladores (digamos B). Me gustaría tenerlo de esta manera porque la división hace que el código sea mucho más limpio. Lo malo es que los controladores adicionales (de tipo B) no son "ciudadanos de primera clase" en la pantalla, por ejemplo, no reciben las consultas y notificaciones de autorrotación. (Y no puede mostrar fácilmente los controladores modales, tienen que enviar el mensaje presentModal… a su controlador principal).¿Controladores de vista múltiple en la pantalla a la vez?

¿Cuál es la diferencia entre los controladores A y B desde el punto de vista de Cocoa? ¿Mantiene el sistema algún tipo de puntero al "controlador frontal", uno privilegiado al que envía notificaciones y esas cosas? ¿Por qué los otros controladores no los reciben, a pesar de que sus puntos de vista están en la pantalla? ¿Tener varios controladores "en pantalla" es considerado un truco? ¿O es compatible y solo me falta algún punto? Gracias.


Más sobre el problema que estoy tratando de resolver: Estoy escribiendo un navegador de fotos simple. Las fotos se muestran en pantalla completa, el usuario puede deslizar hacia la izquierda o hacia la derecha para cambiar las fotos. El controlador A se encarga de la parte de desplazamiento y los controladores B se encargan de cada fotografía.

Aislamiento B parecía una buena idea, ya que las fotos se cargan desde la red y hay muchas cosas que pueden suceder, como la red podría estar abajo, etcétera. En el controlador B, el código es bastante simple, ya que B solo funciona con una foto en particular. Si moviera el código al controlador A, las cosas se pondrían complicadas.

Lo único que no me gusta de la solución actual es que tengo que trabajar manualmente para que B no sea un controlador de "primera clase". Tengo que pasar algunas llamadas manualmente de A a B y cuando B quiere mostrar un diálogo modal, tiene que enviar el presentModal… a A. Lo cual es feo.

Respuesta

7

En primer lugar, y esto es importante, mira controladores no reciben "en la pantalla" - vistas hacen. Su controlador de "nivel superior" ciertamente puede transmitir los tipos de mensajes que está describiendo a sus "controladores de subvista". De hecho, así es como funcionan la mayoría de las aplicaciones. Considere una aplicación que tiene una barra de pestañas, y donde las vistas usan controles de navegación. De hecho, tiene varios controladores de vista "en ejecución" al mismo tiempo, cada uno con su propia vista en pantalla a la vez: su controlador de vista "raíz" será una instancia (o subclase) de UITabBarController, que tiene varios UINavigationControllers anidados, cada uno que mostrará controladores de vista anidados (como una instancia o una subclase de UITableViewController).

Es posible que desee leer un poco sobre cómo funciona responder chains. Considera un evento táctil. Se generará para la vista más cercana a la parte superior de la pila, que puede recibir eventos, que también está debajo del grifo. Si esa vista no puede manejarlo, se pasa a la cadena alimentaria de la jerarquía de vistas hasta que algo se ocupe de eso (y luego se lo coma).

En cuanto a los detalles de su pregunta, en general, no estoy seguro de lo que la estrategia que describe realmente está haciendo para beneficiarlo en términos de complejidad. Depende de cómo se implemente exactamente, pero tener controladores de vista separados para cada pequeña subvista puede requerir más código de contabilidad que solo tener un controlador de vista que conozca todos sus componentes de subvista.

+0

Buena respuesta, gracias.Sé que los puntos de vista aparecen en la pantalla, no en los controladores, es por eso que seguí escribiendo "en pantalla" entre comillas, lo que significa "tener su vista en la pantalla". Escribiré más sobre la situación en la pregunta. – zoul

12

No está estrechamente relacionado con la pregunta original, pero es importante.Apple indica claramente en View Controller Programming Guide que un controlador de vista es responsable de controlar exactamente el contenido de una pantalla:

"Cada objeto de controlador de vista personalizada que crea es responsable de administrar exactamente el contenido de una pantalla. la correspondencia entre un controlador de vista y una pantalla es una consideración muy importante en el diseño de su aplicación. No debe usar múltiples controles de vista personalizados para administrar diferentes partes de la misma pantalla. Del mismo modo, no debe usar un único objeto de control de vista personalizado para Administre varias pantallas con valor de contenido

Nota: Si desea dividir una sola pantalla en varias áreas y administrarlas por separado, utilice objetos de controlador genéricos (objetos personalizados de scending from NSObject) en lugar de ver los objetos del controlador para administrar cada subsección de la pantalla. A continuación, utilice un objeto de controlador de vista única para administrar los objetos de controlador genéricos. El controlador de vista coordina las interacciones globales pantalla pero reenvía mensajes según sea necesario para los objetos de controlador genérico que gestiona "

Sin embargo en la Guía de Programación iPad también dicen que puede haber controladores de vista envase:

". Un controlador de vista es responsable de una vista única. La mayoría de las veces, se espera que la vista de un controlador de vista llene todo el espacio de la ventana de la aplicación. Sin embargo, en algunos casos, un controlador de vista puede integrarse dentro de otro controlador de vista (conocido como controlador de vista de contenedor) y presentarse junto con otro contenido. Los controladores de navegación y barra de pestañas son ejemplos de controladores de vista de contenedor. "

Hasta mi conocimiento actual no usaría controladores de subvista en un controlador de vista pero trataré de subclase NSObject y les enviaré mensajes desde mi controlador de vista principal.

también puedes ver en este tema: MGSplitViewController discussion

+1

El problema es cómo pasar un mensaje desde el objeto de controlador genérico NSObject al controlador de vista. Necesitaría delegados o NSNotifications, lo cual es un problema. – mskw

5

en realidad se puede hacer que funcione antes de iOS 5, desde entonces. la mayoría de nosotros somos ta rgeting 4.x y 5.x al mismo tiempo. Creé una solución que funciona en ambos, y funciona muy bien, pocas aplicaciones en la tienda de aplicaciones lo utilizan :) Lea my article about this o simplemente download and use a simple class que he creado para este fin.

+0

Apple considera que es una mala práctica hacerlo antes de ios5 (es decir, antes de que tuviéramos la contención proporcionada por Apple). Los ingenieros de Apple me lo dijeron en persona. – ader

+0

He estado usando esta solución durante más de un año, y nunca tuve ningún problema con ella. El problema es que la mayoría de las implementaciones que he visto no se ocuparon de manejar adecuadamente la memoria y todos los métodos importantes, y el mío SÍ lo maneja correctamente. Tanto como I love apple view, la contención del controlador debería introducirse con el lanzamiento del iPad, ya que este es el escenario más común para múltiples controladores de visualización. De nuevo, esta es una solución que está aprobada en muchas aplicaciones de la tienda de aplicaciones. Esta solución permite reutilizar los controladores de vista de iPhone sin ningún problema o dolor de cabeza. –

4

Esta es una pregunta muy antigua, pero como creo que hay personas que podrían enfrentar el mismo problema hoy, me gustaría compartir mi solución. Estaba escribiendo esta aplicación que tenía esta pantalla con mucha información, paginación, controles, etc. Dado que según el MVC documentation de Apple sobre el rol de ViewControllers, no debería implementar la lógica en sí misma o acceder al modelo de datos directamente a partir de ello, tuve que elegir entre tener un ViewController masivo con unas mil líneas de código que era difícil de mantener y depurar (incluso con pruebas unitarias) o encontrar una nueva forma.

Mi solución fue usar UIContainerView, como a continuación: enter image description here

esta manera, se puede implementar la lógica de cada parte en su propio ViewController, y el controlador de vista padre se ocupa de las limitaciones y dimensionamiento de las vistas.

Nota: Esta respuesta es sólo una guía para mostrar el camino, se puede encontrar una explicación detallada sobre el bien y cómo funciona y cómo ponerlo en práctica HERE

Cuestiones relacionadas