Conexión de la interfaz con el código fuente: XCode + Interface Builder | Objective C

Conexión de la interfaz con el código fuente: XCode + Interface Builder | Objective C

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

  • El modelo encapsula el estado de la aplicación, contiene los datos, notifica de cambios, etc. La vista representa en pantalla los modelos, pide actualizaciones de estos, envía gestos al controlador, permite al controlador seleccionar una vista, etc. Y el Controlador define el marco de la aplicación, selecciona una vista para la respuesta a una petición, etc.

    ahora la versión de Cocoa:
    si combinamos el MVC con la aplicación, el modelo de datos y las vistas de cocoa junto con los controladores, esto es lo que obtenemos:
    Con este patrón podemos separar el código en función de lo que hace.
  • Como hemos visto, los controladores no deciden totalmente lo que hacer con las vistas sino que son estas las que les dicen cuáles pueden utilizar, lo cual no es totalmente un patrón MVC sino Modelo-Vista-Presentación, aquí tenéis el esquema real del funcionamiento actual de una aplicación en iOS:

    que se puede ver así representado :
      

    Leer más acerca de la diferencia entre MVC y MVP »

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:

 

footer
jbelon © | sitemap.xml