Añadir elementos a mano en UITableView
16 June 2008
(Los fuentes del ejemplo están disponibles en el pie del artículo).
Tras la trilogía de SQLite con UITableView, donde veíamos como mantener nuestro TableView apoyado en una base de datos de SQLite, hemos pensado en mostrar otro ejemplo pero esta vez algo más sencillo, para ver el funcionamiento sencillo de dicho control añadiendo elementos de forma manual a nuestro TableView.
La forma de ver nuestro ejemplo en funcionamiento parte de la creación de un nuevo proyecto de tipo Navigation-Based Application, el cual nos creará un proyecto con un control de tipo UITableView por defecto y un control de tipo barra de navegación Navigation Bar.

RootViewController.xib y MainWindow.xib son los dos ficheros de recursos creados por el asistente para nuestro proyecto. El primero contiene el control tipo UITableView para nuestro ejemplo y el segundo fichero de recursos contiene, además de la ventana principal de nuestra aplicación, el anterior control de tipo UITableView insertado bajo nuestra barra de navegación Navigation Bar.
Aunque esta operación de incluir un fichero de recursos dentro de otro la ha realizado el asistente de forma automática, la forma manual de hacerlo es simplemente añadiendo bajo nuestro controlador de navegación Navigation Controller un controlador de tipo View Controller. Una vez insertado tendremos que cambiar desde nuestra ventana de atributos la opción de NIB Name para saber de que recurso tira y la opción de Class, para indicarle que clase será la encargada de gestionar dicho controlador. De momento dejemos el proyecto como lo creó el asistente y continuemos.



Es conveniente que nuestro control TableView este gestionado por su propia clase, en este caso RootViewController, para aislar el comportamiento de dicho control y como no, encapsular de forma correcta el código. Además, nuestro control deberá heredar de la clase UITableViewController, la cual ya nos proporciona gran parte de la funcionalidad del mismo y la opción de capturar mensajes relacionados, y la forma correcta de hacerlo, es gestionándolo con su propia clase.
- AÑADIMOS BOTONES DE AÑADIR Y ELIMINAR A NUESTRA BARRA DE NAVEGACIÓN -
Lo siguiente que haremos será añadir un par de botones para insertar y eliminar elementos a nuestro TableView. Si nos fijamos mediante Interface Builder en nuestro control Navigation Item, veremos que ya se encuentran definidos los estados backBarButtonItem, leftBarButtonItem y rightBarButtonItem, los cuales nos permiten añadir botones en las tres posiciones de nuestra barra de navegación.
En este momento os vuelvo a recordar como en un anterior artículo, el uso de la documentación de xCode, pues la misma me ha permitido encontrar que tipo de botón quiero insertar. He localizado buscando UIBarButtonItem, que puedo añadir un botón personalizado utilizando la función initWithTitle.
Los he creado tanto a izquierda como a derecha de nuestra barra de navegación, y para ambos botones, he definido a que función llamarán cuando sean pulsados, addItem y delItem.
[cpp]
UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithTitle:@"Añadir" style:UIBarButtonItemStylePlain target:self action:@selector(addItem:)];
self.navigationItem.leftBarButtonItem = addItem;
[addItem release];
UIBarButtonItem *delItem = [[UIBarButtonItem alloc] initWithTitle:@"Eliminar" style:UIBarButtonItemStylePlain target:self action:@selector(delItem:)];
self.navigationItem.rightBarButtonItem = delItem;
[delItem release];
[/cpp]
Una vez creadas ambas funciones, ya solo nos queda implementarlas para que añadan o eliminen elementos. La forma de añadir y eliminar elementos siempre debemos hacerla en base a alguna estructura en memoria. Es decir, en nuestro ejemplo, al insertar y eliminar elementos, realmente lo hacemos sobre un array en memoria, y gracias a métodos de UITableView como numberOfRowsInSection (devuelve el número de elementos de nuestro TableView) y de cellForRowAtIndexPath (devuelve una celda de una determinada posición), tendremos nuestro TableView actualizado con los elementos que tenemos en nuestro array.
Así, al añadir, insertamos un elemento en el array y forzamos a actualizar nuestro TableView mediante reloadData. Dicha llamada, forzará a que nuestro TableView nos devuelva el número de filas que va a mostrar (numberOfRowsInSection), y si devuelve más de 0, automaticamente también forzará a que se pinten las celdas (cellForRowAtIndexPath). Para eliminar, haremos exactamente igual, eliminaremos un elemento de nuestro array y llamaremos de nuevo a reloadData.
[cpp]
- (void)addItem:(id)sender {
NSUInteger count = [self.elementos count];
[self.elementos insertObject:@"elemento" atIndex:count];
[self.tableView reloadData];
}
- (void)delItem:(id)sender {
NSIndexPath* selected = (NSIndexPath*)[self.tableView indexPathForSelectedRow];
[self.elementos removeObjectAtIndex:selected.row];
[self.tableView reloadData];
}
[/cpp]
En definitiva y para resumir, nosotros nos encargaremos de mantener un array u otra estructura en memoria, y cuando hagamos una llamada a reloadData de nuestro TableView, este nos hará dos preguntas en forma de métodos:
1. numberOfRowsInSection: ¿Cuantas filas quieres que pinte?
2. cellForRowAtIndexPath: ¿Que fila pinto en esta posición?
Espero que os haya servido de ayuda. Se aceptan comentarios.
Descargar: uitableview.zip
Tras la trilogía de SQLite con UITableView, donde veíamos como mantener nuestro TableView apoyado en una base de datos de SQLite, hemos pensado en mostrar otro ejemplo pero esta vez algo más sencillo, para ver el funcionamiento sencillo de dicho control añadiendo elementos de forma manual a nuestro TableView.
La forma de ver nuestro ejemplo en funcionamiento parte de la creación de un nuevo proyecto de tipo Navigation-Based Application, el cual nos creará un proyecto con un control de tipo UITableView por defecto y un control de tipo barra de navegación Navigation Bar.

RootViewController.xib y MainWindow.xib son los dos ficheros de recursos creados por el asistente para nuestro proyecto. El primero contiene el control tipo UITableView para nuestro ejemplo y el segundo fichero de recursos contiene, además de la ventana principal de nuestra aplicación, el anterior control de tipo UITableView insertado bajo nuestra barra de navegación Navigation Bar.
Aunque esta operación de incluir un fichero de recursos dentro de otro la ha realizado el asistente de forma automática, la forma manual de hacerlo es simplemente añadiendo bajo nuestro controlador de navegación Navigation Controller un controlador de tipo View Controller. Una vez insertado tendremos que cambiar desde nuestra ventana de atributos la opción de NIB Name para saber de que recurso tira y la opción de Class, para indicarle que clase será la encargada de gestionar dicho controlador. De momento dejemos el proyecto como lo creó el asistente y continuemos.



Es conveniente que nuestro control TableView este gestionado por su propia clase, en este caso RootViewController, para aislar el comportamiento de dicho control y como no, encapsular de forma correcta el código. Además, nuestro control deberá heredar de la clase UITableViewController, la cual ya nos proporciona gran parte de la funcionalidad del mismo y la opción de capturar mensajes relacionados, y la forma correcta de hacerlo, es gestionándolo con su propia clase.
- AÑADIMOS BOTONES DE AÑADIR Y ELIMINAR A NUESTRA BARRA DE NAVEGACIÓN -
Lo siguiente que haremos será añadir un par de botones para insertar y eliminar elementos a nuestro TableView. Si nos fijamos mediante Interface Builder en nuestro control Navigation Item, veremos que ya se encuentran definidos los estados backBarButtonItem, leftBarButtonItem y rightBarButtonItem, los cuales nos permiten añadir botones en las tres posiciones de nuestra barra de navegación.
En este momento os vuelvo a recordar como en un anterior artículo, el uso de la documentación de xCode, pues la misma me ha permitido encontrar que tipo de botón quiero insertar. He localizado buscando UIBarButtonItem, que puedo añadir un botón personalizado utilizando la función initWithTitle.
Los he creado tanto a izquierda como a derecha de nuestra barra de navegación, y para ambos botones, he definido a que función llamarán cuando sean pulsados, addItem y delItem.
[cpp]
UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithTitle:@"Añadir" style:UIBarButtonItemStylePlain target:self action:@selector(addItem:)];
self.navigationItem.leftBarButtonItem = addItem;
[addItem release];
UIBarButtonItem *delItem = [[UIBarButtonItem alloc] initWithTitle:@"Eliminar" style:UIBarButtonItemStylePlain target:self action:@selector(delItem:)];
self.navigationItem.rightBarButtonItem = delItem;
[delItem release];
[/cpp]
Una vez creadas ambas funciones, ya solo nos queda implementarlas para que añadan o eliminen elementos. La forma de añadir y eliminar elementos siempre debemos hacerla en base a alguna estructura en memoria. Es decir, en nuestro ejemplo, al insertar y eliminar elementos, realmente lo hacemos sobre un array en memoria, y gracias a métodos de UITableView como numberOfRowsInSection (devuelve el número de elementos de nuestro TableView) y de cellForRowAtIndexPath (devuelve una celda de una determinada posición), tendremos nuestro TableView actualizado con los elementos que tenemos en nuestro array.
Así, al añadir, insertamos un elemento en el array y forzamos a actualizar nuestro TableView mediante reloadData. Dicha llamada, forzará a que nuestro TableView nos devuelva el número de filas que va a mostrar (numberOfRowsInSection), y si devuelve más de 0, automaticamente también forzará a que se pinten las celdas (cellForRowAtIndexPath). Para eliminar, haremos exactamente igual, eliminaremos un elemento de nuestro array y llamaremos de nuevo a reloadData.
[cpp]
- (void)addItem:(id)sender {
NSUInteger count = [self.elementos count];
[self.elementos insertObject:@"elemento" atIndex:count];
[self.tableView reloadData];
}
- (void)delItem:(id)sender {
NSIndexPath* selected = (NSIndexPath*)[self.tableView indexPathForSelectedRow];
[self.elementos removeObjectAtIndex:selected.row];
[self.tableView reloadData];
}
[/cpp]
En definitiva y para resumir, nosotros nos encargaremos de mantener un array u otra estructura en memoria, y cuando hagamos una llamada a reloadData de nuestro TableView, este nos hará dos preguntas en forma de métodos:
1. numberOfRowsInSection: ¿Cuantas filas quieres que pinte?
2. cellForRowAtIndexPath: ¿Que fila pinto en esta posición?
Espero que os haya servido de ayuda. Se aceptan comentarios.
Descargar: uitableview.zip

Comentarios recientes
De nada, para eso esta este Blog. Saludos.
Gracias! ya lo consegui gracias a sus ejemplos...
Divide la pantalla con dos vistas y cargas la tabla en una de ellas. Como en el ejemplo del nivel piolin. Saludos.
Seguro que hay manera de hacerlo. Dejame mirarlo, pero te aconsejo que publiques estas dudas en el foro ya que más gente te contestará. Saludos.
una duda amigo, como hago para crear una tabla pero que no abarque toda la pantalla, sino la mitad de ella, y sea scrollable y todo como normalmente es, pero tener la otra mitad de la vista libre para colocar otros componentes... esto es posible? ya que no lo he logrado hacer... gracias
Realmente no asocias el array. Te lo creas como un objeto de tu clase, trabajas con él, y lo utilizas en los dos métodos de TableView que he comentado. Es una estructura independiente, no asociada. Bájate el ejemplo que he subido. Saludos
La única duda que me surge es, ¿cómo asocio el array que quiero y no otro a la tableview?.
Deja un comentario