martes, 7 de junio de 2011 | Sin Comentarios
Conexión de la interfaz con el código: aplicaciones de iOS
Un poco de teoría: Diseño de la aplicación
Guía de estilo para la interfaz de usuario: PDF.
MVC & Eventos
- El patrón de ingeniería del software Modelo-Vista-Controlador actúa en base a clases que tienen la forma: el Modelo define las estructuras de datos, la Vista las ventanas, widgets, etc. que interactúan por medio de los Controladores que unifica los dos anteriores y en sus acciones determina cómo manejar los eventos.
- Estos eventos pueden ser de varios tipos: un gesto (o gesture: secuencia de eventos desde que el usuario toca la pantalla hasta que deja de hacerlo), toque (touch: el dedo está en la pantalla) y el clásico click o tap que es cuando el usuario toca la pantalla por un instante. A los eventos se les captura por medio de una cadena de clases UIResponder,
que responden una a una, esto se logra con la herencia (subclases de UIView, UIControl,etc.)
siendo la primera de las instancias que responden la que interactúa con el usuario. Lo que se hace una vez despachado el evento por el primer Responder es redirigirlo al siguiente respondedor a mano con la función «nextResponder».
- Podemos controlar los eventos de tipo Touch, siendo estos pertenecientes a una vista sobrecargando la función «touchesBegan», capturando así el inicio de la interacción:
– (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSUInteger numTaps = [[touches anyObject tapCount;
NSUInteger numTouches = [touches count;
}
Podéis seguir investigando con métodos como touchesMoved, touchesEnded y touchesCancelled. Con locationInView obtenemos la posición del touch.
Más información >
- Tipos de gestos: swipe (sigue la acción del usuario en un eje determinado, puede implicar dragging o arrastrar y soltar –UIPanGestureRecognizer-) -> UISwipeGestureRecognizer, tapping (cualquier número de toques) -> UITapGestureRecognizer, pinching (acercar o alejar dedos para zoom por ejemplo), rotating (mover dedos en direcciones opuestas) -> UIRotationGestureRecognizer y long press (tocar y mantener) -> UILongPressGestureRecognizer. Todas estas clases reconocedoras son utilizables por medio de la declaración de una clase (entre paréntesis) asociada a la ventana UIWindow (que está asociada a una UIApplication al mismo tiempo) y hace posible la gestión de estos eventos:
Los posibles estados con sus transiciones:
Evidentemente ,un gesto contínuo lanzará varios eventos para poder hacer un seguimiento del mismo, mientras que uno discreto sólo tendrá un evento.
- Los eventos de movimiento están encapsulados por el objeto CMAccelerometerData que guarda en una estructura la aceleración sobre cada uno de los ejes espaciales. CMGyroData guarda datos sobre la velocidad y CMDeviceMotion encapsula varias medidas, incluyendo la postura, rotación y aceleración. El acelerómetro se ha de configurar antes de usarse, con la clase UIAccelerometer definimos los parámetros.
- La orientación se obtiene con la clase UIDevice invocando el método beginGeneratingDeviceOrientationNotifications, hay un begin y un end para gestionar la secuencia.
- El tipo de eventos que necesitan recoger información de los sensores del giroscopio y el acelerómetro deben ser los primeros en responder por lo que usamos la función canBecomeFirstResponder de una vista y si tenemos permiso entonces activamos con beginReceivingRemoteControlEvent,y desactivándolo cuando no se use la vista con resignFirstResponder.
- Éste es el ciclo de vida de una aplicación, podemos ver como se enmarca la gestión de eventos justo en mitad del loop de eventos:
Recordemos MVC
Conexión del constructor de interfaces (I.B.) con las vistas: los controladores de las vistas y los modelos
Controladores de las Vistas
Sabemos que una instancia de una clase controlador tiene la lógica que une los datos de un modelo de una aplicación con las entidades visuales usadas para presentarlos al usuario en el dispositivo. En iOS ,los controladores de las vistas o View Controllers, son objetos que heredan de la clase genérica de Objective C llamada UIViewController. Gracias a los controladores de las vistas definimos el comportamiento de las interfaces de usuario, podemos encontrar tres tipos de controladores de vistas:
- Custom View Controller: para representar a «nuestra manera» la información, es algo más personalizado; se usa en listas de elementos, presentaciones de estos, propiedades, etc. ( ejemplos: de un UITableViewCell -> UIViewController)
- Container View Controller: sirven para embeber dentro a otros controladores de vistas, definiendo relaciones de navegación entre ellos, suelen utilizarse de forma automatizada los que trae el sistema por defecto (ejemplos: UITabBarController, UINavigationController), establecen relaciones entre controladores
- Modal View Controller: describen las relaciones entre controladores y cómo modifican la representación de los datos, puede ser utilizado por cualquier controlador (en realidad es un modo de funcionamiento, la ventana modal, que no permite continuar con el resto de la aplicación hasta que se ha cerrado la vista/ventana modal)
Por dónde empezar
- Hemos visto que los eventos se gestionan en mitad del ciclo de vida de una aplicación, lo que pasa antes y después se puede controlar por medio del denominado «Application Delegate», que no es otra cosa que los eventos que ocurren antes ,durante y después del inicio de una aplicación. XCode genera por defecto los archivos {nombre_proyecto}AppDelegate.h y .m que contienen el código que se ejecuta cuando la aplicación se lanza y finaliza, aprovecharemos estas funciones para cargar datos, inicializar componentes, etc. Luego sólo cargar la aplicación, este es el esquema de funcionamiento de iOS:
una vez cargada, puede pasar al estado en segundo plano, de modo que quedaría así:
si,ahora es cuando deberíamos programar los eventos de la clase {loquesea}ApplicationDelegate para descargar memoria o realizar tareas de sincronización mientras trabaja en segundo plano…ya hablaremos de eso más adelante en el capítulo de multitarea…podéis leer más acerca de la implementación de funciones en el marco común de comportamiento de la aplicación aquí. Ahora debemos reemplazar el esquema de ciclo de aplicación que vimos antes en los eventos por el nuevo esquema en segundo plano:
y si aún no os queda muy claro, podéis echar un vistazo a este esquema:
sacado de cocoanetics: understanding iOS 4 Backgrounding and delegate messaging
Creación de interfaces con el Interface Builder
Conceptos básicos
- Las interfaces se guardan en ficheros .XIB que es un XML y puede editarse a mano aunque para eso está el editor visual :) Cuando se compilan se genera un NIB que puede usarse para inicializar una vista.
- La manera en que utilizamos los widgets, ventanas, vistas y demás objetos en el código es a través de un outlet (llamado IBOutlet en el código), tenemos que definir una variable con este apóstrofe y luego el tipo que sea, normalmente se llaman UI___ por lo que es fácil distinguir las clases de la interfaz. Al posponer la palabra clave IBOutlet a una variable no modifica ni su contenido ni su comportamiento, pero avisa al compilador y al I.B. de que puede ser conectada a un objeto de interfaz incluído en el XIB asociado a dicha clase
- Para definir acciones, es decir, funciones que se puedan activar a través de un evento generado por un elemento de la interfaz (de una vista), utilizamos las bien denominadas IBAction en el código, en este caso el prefijo que se utiliza para definir una función es como un tipo de dato, por lo que si afecta a la declaración de una función ( y no se pueden utilizar dos tipos seguidos en la declaración, recordemos Objective C ) . IBAction indica al editor de interfaces que la función se utiliza por objetos para eventos concretos, como pueda ser, pulsar un botón o cualquier otro…
Interface Builder: ¿qué es?
- Editor que provee de una paleta de objetos para el interfaz de programación con Objective C
- Objetos asociados: cada .xib tiene una clase asociada, este objeto dentro de la ventana de edición de interfaz se llama «File’s owner», y si recordamos lo que era el first responder, pues este objeto representa al que el usuario tiene asociado para interaccionar, lo mismo pasa con View, que es la vista principal de la clase. Para realizar las asociaciones usamos el botón derecho del ratón y arrastrando y soltando asignamos los outlets y actions que hayamos definido en el código ( Ver ejemplo de asociación )
…simple
- Gracias a la ventana de la biblioteca de objetos podremos arrastrar y soltar los widgets, vistas, etc. que necesitemos y por medio del inspector editamos los atributos de estos, podemos escribir una clase que luego sea la que controle un objeto (aquí la definimos)
Ejercicio:
Escribe un proyecto nuevo View-Based, abre la vista principal y crea una label, desde el código crea una asociación con un atributo -> propiedad con el prefijo IBOutlet, asóciala en el I.B. y luego en el evento de recién cargada la aplicación (appdelegate -> didlaunch with options) accede a dicho objeto de la interfaz para establecer el texto «Hola mundo», algo sencillo, puedo corregírtela si me la envías en el formulario de contacto.
<< Volver al curso de programación de aplicaciones de iOS
Siguiente: Persistencia de datos en iOS y Google Web Toolkit (Google App Engine) >>
Artículos relacionados:
Deja tu comentario