iOS Programming, Objective C

Tablas en iOS

Recién comienzo a introducirme en el desarrollo de aplicaciones en iOS y lo que vaya aprendiendo se los estaré compartiendo. Además de esto, es importante que para seguir este tutorial, ya tengas los conocimientos básicos de Objective-C, definir clases, métodos, enviar mensajes (llamar métodos pues!).

Así que una vez aclarado que no soy experto y que puede haber errores en este tutorial y definidos los requisitos previos, iniciemos pues!!

UIView, UIViewController… Controladores? Vistas?

Bien, primero que nada, hay que saber que UIView es algo así como la clase de la cual los elementos gráficos de la interfaz de usuario que vemos en el iOS derivan. En términos formales, la documentación de Apple, nos dice:

«La clase UIView define un área rectangular sobre la pantalla y las interfaces para manejar el contenido en esta área…..»

Existe una clase llamada UITableView que representa una tabla en iOS. Esta clase deriva de UIView. Debemos saber que al ser iOS un sistema operativo para dispositivos móviles iPhone/iPad, en el caso de iPhone, la pantalla es muy pequeña, por lo cual, un UITableView no tiene columnas, únicamente filas!!!!!!! y entonces?, tranquilo :), no las vamos a necesitar en este tipo de programación! Y en dado caso que lo hagamos, seguramente habrá una forma de simular columnas! :p

Bien, los elementos de la interfaz de usuario de iOS siguen el diseño MVC, así que el UITableView es la vista. ¿Y el controlador?, bueno, básicamente estos elementos de la interfaz de usuario, tienen sus correspondientes controladores, en el caso de UIViewTable tiene su correspondiente controlador llamado IUTableViewController que efectivamente, hereda de UIViewController.

Básicamente, un UITableView necesita de:

  1. Un controlador de vista. Este controlador será el que maneje su apariencia sobre la pantalla.
  2. Un «data source» ya que el UITableView le pregunta sobre el número de registros a mostrar. Sin un data source, el UITable simplemente será un contenedor vacío como lo veremos más adelante. Este data source puede ser cualquier objeto de Objective-C, pero siempre y cuando implemente al protocolo UITableViewDataSource.
  3. Un delegado. Este delegado se encargará de informar a otros objetos de aquellos eventos relacionados con el UITableView. Al igual que el data source, este delegado podrá ser cualquier objeto Objective-C que implemente al protocolo UITableViewDelegate.

Ok, pues esto es lo que se necesita para mostrar una tabla en iOS. Afortunadamente, un objeto de la clase UITableViewController cubre las 3 reglas anteriores.

Por decirlo de alguna forma, el UITableView es muy tonto, no sabe mucho, pero el UITableViewController vaya que es inteligente, y este es el encargado de saber cuál es su vista, que será un UITableView. En el fondo, un UITableViewController es una instancia de UITableView, entiendo que es algo así como un envoltorio que maneja su preparación y presentación del UITableView. Cuando un UITableViewController crea su vista, las variables de instancia «dataSource» y «delegate» del UITableView, apuntan automáticamente a el UITableViewController.

Manos a la obra!!

Requisitos.

  1. Mac OS X 10.7 Lion.
  2. XCode 4.2

Una vez que vimos algo de teoría aburrida, vayamos a la práctica! En Xcode vamos a crear un nuevo nuevo proyecto iOS tal y como se muestra en las siguientes imagenes.

Bien, una vez que creamos el proyecto, vamos a agregar una nueva clase Objective-C que herede de UITableViewController ya que como les decía arriba, esta clase ya tiene una vista UITableView y además ya proporciona un delegado y un datasource.

El asistente nos creara las clases y al indicarle que será una subclase de UITableViewController, pues implementará algunos métodos de esta clase, así que por el momentos, no se espanten de ver tanto código en nuestra nueva clase ListOfMonthsViewController. De igual forma, si reciben algunos warnings por parte del compilador, vamos a omitirlos en este ejercicio.

Hay que saber que un UITableView tiene dos tipos de estilos, la simple y la agrupada. La simple es solo eso, una lista de celdas de color blanco. La agrupada, es aquella cuya presentación se hace mediante secciones, por ejemplo en nuestra lista de contactos que tenemos en el iOS es un ejemplo de lista agrupada, ó por ejemplo lo que muestra la siguiente imagen es otra tabla con estilo de vista agrupado.

Xcode nos crea ya varios archivos. En el ListOfMonthsViewController.m localicemos el inicializador o como se le llama en casi la mayoría de los lenguajes, el constructor.

El código anterior, sencillamente llama al constructor de su clase padre, UIViewController. Aquí es donde se le indica que estilo de tabla deseamos, en este caso, será el valor que tenga «sytle».

Bien, lo único que vamos a hacer es abrir la clase ByteAppDelegate.m (no te confundas, este es el delegado de la ventana y no del UITableView).

Localizamos el método que se ve en la imagen y agregamos el código marcado.

Cuando se lanza la aplicación, se envía el mensaje «application:didFinishLaunchingWithOptions» justo cuando el «lanzado» de la aplicación se completa. (Hay que recordar que en Objective-C se acostumbra más usar la terminología «envio de mensajes» que la «llamada a métodos»). Por lo que en el momento que la aplicación es lanzada, es cuando debemos crear el controlador de nuestra tabla. Una vez que el controlador de vista es creado, lo único que necesitamos hacer es establecerlo como raíz del UIWindow. UIWindow es la ventana básicamente y sobre esta ventana, es donde «insertamos» nuestra vista «principal» que será una tabla.

Ahora, si corremos la aplicación con el simulador del iPhone, veremos una pantalla en blanco con algunas filas vacías, esta es la tabla con estilo plano!

Cambiemos el estilo con el que iniciamos la tabla, en lugar de usar UITableViewStylePlain pongamos UITableViewStyleGrouped

Corramos la aplicación nuevamente y veremos que la pantalla ahora tiene un estilo gris. Hasta ahora, esta es nuestra tabla, quizá no lo parezca pues le faltan datos, pero ahí esta.

Vamos a mostrar algunos datos. Recordemos que nuestro UITableViewController funge también como delegado. Para mantener la sencillez del tutorial (que de por sí imagino ya compliqué), vamos a definir una variable de instancia NSMutableArray en el ListOfMonthsViewController.h

 

 

Y en el inicializador de ListOfMonthsViewController.m vamos a llenarlo con algunos datos fijos.

 

Vamos a recapitular un poco el flujo que nuestra mini aplicación sigue.

Al lanzar la aplicación, se envia el mensaje application:didFinishLaunchingWithOptions y aquí se crea una vista UIWindow. (ver el ByteAppDelegate). Inmediatamente, creamos nuestro controlador ListOfMonthsViewController, este controlador creara nuestra vista UITable con un estilo «plain». En el momento que creamos el objeto ListOfMonthsViewController, vemos que en su inicializador (constructor) hemos inicializado nuestro array con los nombres de los meses.

Ya que se crearon los meses, el control vuelve nuevamente al método application:didFinishLaunchingWithOptions de ByteAppDelegate y se establece como «rootViewController» al recien creado ListOfMonthsViewController.

Una vez que esto pasa, la vista de tabla esta creada y entonces esta misma tabla envia varios mensajes a su delegado, entre los mensajes que envía son:

  • tableView:numberOfRowsInSection:
  • tableView:cellForRowAtIndexPath

¿Pero quien es el delegado de nuestra tabla?… Como lo mencione al inicio del artículo, el mismo UITableViewController funge como delegado y datasource, así que la clase ListOfMonthsViewController es el delegado y es quien recibe los mensajes anteriores.

¿Confundido?… tranquilo. Termina el ejercicio, y una vez que veas el resultado, vuelve a leer esta teoría y seguro le entenderas.

Lo que quise decir con lo anterior, es que debemos agregar los dos métodos anteriores a nuestro controlador, en este caso, como los creamos con Xcode, pues dichos métodos ya los tenemos, solo es cuestión de buscarlos.

Primero, que nada, debemos indicarle al controlador cuantas filas por sección será capaz de mostrar nuestra tabla! Recordemos que una tabla puede estar dividida en secciones y cada sección tiene un número determinado de filas. En nuestro caso, como vamos a utilizar el estilo plano, este estio tiene solamente 1 sección, y ¿cuantas filas tendrá?… pues tendrá X número de filas como nuestro arreglo de meses contenga!! en este caso, tendrá 12 filas que corresponde con los 12 meses del año….

ok, ¿y en donde le indicamos esto?

Cuando la vista de tabla es creada, envía varios mensajes al delegado, entre ellos envía el mensaje «tableView:numberOfRowsInSection:» y aquí es donde debemos indicarle el número de registros a mostrar en casa sección. Si hubieramos configurado nuestra tabla para tener 3 secciones, este método se invocaría 3 veces, si tuviera 5 secciones, se invocaría 5 veces… etc.

Bien, vamos a buscar dicho método y agregar lo siguiente:

 

 

Listo!!! Nuestra tabla tendrá 12 filas en su única sección.

Una vez que el controlador conoce el número de filas que tendrá la tabla, envía el mensaje «tableView:cellForRowAtIndexPath:» por cada fila que se tenga.

Aquí es donde entonces debemos escribir el contenido que tendrá cada celda (dado que el UITableView no tiene columnas, el usar filas o celdas, será casi lo mismo).

Localizamos dicho método, borramos por el momento el código que tiene ahí y escribimos lo siguiente.

 

Llegado a este punto, es necesario aclarar algo.

Las celdas del IUTableView son también objetos de una clase llamada UITableViewCell, es decir, las celdas también son vistas! Entonces, una celda es una sub-vista de nuestra tabla! Existen 4 estilos de celdas, por el momento, solo mencionaremos el estilo UITableViewCellStyleDefault.

El código anterior, parece ser claro y descriptivo por si mismo, así que no invertiré tiempo en explicarlo.

Ya pues! Vayamos a correr este sencillo ejemplo con el simulador del iPhone y veamos el resultado.

 

Bueno, ya me he alargado mucho en este tutorial, así que le vamos a dejar aquí por esta vez, pero escribiré una segunda parte donde continuaremos con este ejercicio y veremos algunas características más de un  UITableView.

Si te ha sido útil esta información, solo basta dejar un comentario! Saludos!!