sábado, 21 de abril de 2012

Editando un UITableView: insertar filas

Cuando utilicéis UITableView, en muchas ocasiones en necesario permitir al usuario insertar y eliminar filas.  Borrarlas es bastante sencillo, pero insertarlas es algo un poco más complejo. Os voy a mostrar un ejemplo de como se puede hacer. 



Supongamos que tenemos el típico table view controller con el botón de editar en la parte superior derecha, algo del estilo a la siguiente imagen:



Y queréis que, al pulsar el botón Edit, además de que aparezca el simbolo a la derecha para borrar filas, también os añada una nueva al final en la que podais introducir un nuevo texto. Es decir, algo así:



La plantilla que nos proporciona Apple para el UITableViewController ya viene comentado lo que necesitamos para mostrar el botón Edit.  Está en el viewDidLoad y lo único que hay que hacer es descomentarlo. Se trata de la siguiente línea:

self.navigationItem.rightBarButtonItem = self.editButtonItem;

Con esto ya se consigue que, al pulsarlo, nos muestre el símbolo de borrado en las filas existentes del Table View. Pero lo que necesitamos es añadir una fila que permita al usuario introducir nueva información.

Para ello primero vamos a implementar el método tableView:numberOfRowsInSection: del UITableViewDataSource Protocol

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{
    if (self.editing)
        return [self.propertyListData count] + 1;
    else 
        return [self.propertyListData count];
}

Como veis, se comprueba si estamos en modo de edición y, si es así, devuelve el número de filas actuales mas una. propertyListData es en este caso un NSArray que está definido así en el interface:

@property (weak, nonatomic) NSArray *propertyListData;

También hay que añadir código al método tableView:cellForRowAtIndexPath:


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = 
@"PropertyListCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    // Configuramos la celda
    if (indexPath.row >= [self.propertyListData count]  && self.editing// Si es la nueva celda añadida y estamos en modo edición
    {

    // Creamos un campo de texto en la nueva fila
    // Estableciendo las propiedades que se necesiten
        UITextField *addTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 6, 250, 25)];
        addTextField.adjustsFontSizeToFitWidth = YES;
        addTextField.textColor = [UIColor blackColor];
        
      addTextField.placeholder = NSLocalizedString(@"Nueva fila", "New UITableView row");
        addTextField.keyboardType = UIKeyboardTypeDefault;
        addTextField.returnKeyType = UIReturnKeyDone;
        
        addTextField.backgroundColor = [UIColor whiteColor];
        addTextField.autocorrectionType = UITextAutocorrectionTypeNo
        addTextField.autocapitalizationType = UITextAutocapitalizationTypeWords
        addTextField.textAlignment = UITextAlignmentLeft;
        addTextField.tag = 0;
        addTextField.font = [UIFont systemFontOfSize:14];
        addTextField.delegate = self;        
        addTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
        [addTextField setEnabled: YES];

        // Añadimos el textfield al contentView de la celda
        [cell.contentView addSubview:addTextField];
        

    }
    else 
    {
       cell.textLabel.text = [self.propertyListData objectAtIndex:indexPath.row];
    }
    
    cell.textLabel.font = [UIFont systemFontOfSize:14];

    return cell;
}



Otro método a implementar es tableView:editingStyleForRowAtIndexPath: En él se va a indicar el tipo de símbolo que vamos a añadir a la izquierda de la celda cuando esté en modo edición que, en este caso, será el de borrado o el de inserción. Si este método no se sobreescribe aparece el de borrado en todas las filas. Hay que tener en cuenta que las filas se numeran de 0 a n. Entonces, quedará así:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    
    if (indexPath.row == [self.propertyListData count]) 
    {
        return UITableViewCellEditingStyleInsert;
    } 
    else 
    {
        return UITableViewCellEditingStyleDelete;
    }
    
}



Todo esto no es suficiente, también necesitamos indicarle al TableView que hay que insertar una nueva fila y se debe indicar en el momento apropiado. El método adecuado en donde hacerlo es setEditing:animated.

- (void)setEditing:(BOOL)editing animated:(BOOL)animated 
{
    [super setEditing:editing animated:animated];
//Definimos el indexpath en donde vamos a añadir la nueva fila. En este caso será la última fila

    NSIndexPath *ip = [NSIndexPath indexPathForRow:[self.propertyListData count] inSection:0];

    if (editing) //En modo edición, añadimos la fila
    {
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip]
         withRowAnimation:UITableViewRowAnimationBottom];
    } 
    else 
    {
        //Si hemos añadido datos a la nueva fila, las tendremos que añadir al modelo
        if (/*lo que sea, dependerá de vuestra codificación*/
        {

        }
        else //Y si no, la borramos
        {
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationFade];
        }   
    }   
}

Y ya lo tendríamos. Por hoy nada más.

No hay comentarios:

Publicar un comentario