Pregunta Usar filas de inserción en una UITableView


Me gustaría que mi UITableView se comporte como la tabla en el editor de Contactos, es decir, el usuario debería presionar Editar y una fila de "agregar nueva categoría" debería aparecer en la parte inferior de cada sección.

Estoy usando el siguiente código para hacer esto, pero el problema es que no hay una transición fluida como la hay en Contactos. En cambio, la nueva fila aparece de repente. ¿Cómo puedo obtener la animación?

Además, ¿cómo respondo a los clics en la fila "agregar nueva categoría"? La fila no se puede hacer clic en mi implementación actual.

¿Debo volver a cargar los datos cuando el usuario comienza a editarlos? Estoy haciendo esto porque de lo contrario las filas de inserción nunca se dibujan.

Gracias.

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated];
    [tableView reloadData];
}

- (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section {
    // ...
    if( self.tableView.editing ) 
        return 1 + rowCount;
}

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // .....
    NSArray* items = ...;
    if( indexPath.row >= [items count] ) {
        cell.textLabel.text = @"add new category";
    }
    // ...

    return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray* items = ...;

    if( indexPath.row == [items count] )
        return UITableViewCellEditingStyleInsert;

    return UITableViewCellEditingStyleDelete;
}

32
2017-09-24 10:44


origen


Respuestas:


Me faltaba una cosa. En setEditing :, en lugar de llamar a reloadData debería haber hecho:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController

    NSMutableArray* paths = [[NSMutableArray alloc] init];

    // fill paths of insertion rows here

    if( editing )
        [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
    else
        [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];

    [paths release];
}

36
2017-09-25 00:30



La respuesta a los clics en la fila se puede hacer en didSelectRowAtIndexPath método para indexPath.row == [items count]. Para la animación, sugiero echar un vistazo aquí, en el insertRowsAtIndexPaths:withRowAnimation: método. Hay una publicación sobre cómo usarlo aquí.


5
2017-09-24 20:50



Un efecto secundario no deseado de la solución resaltada es que la fila "agregar" también se inserta cuando el usuario simplemente desliza una sola fila (siempre que esté habilitado el deslizamiento). El siguiente código resuelve este dilema:

// Assuming swipeMode is a BOOL property in the class extension.

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Invoked only when swiping, not when pressing the Edit button.
    self.swipeMode = YES;
}

- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.swipeMode = NO;
}

Su código requeriría un pequeño cambio:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController

    if (!self.swipeMode) {

        NSMutableArray* paths = [[NSMutableArray alloc] init];

        // fill paths of insertion rows here

        if( editing )
            [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
        else
            [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
        [paths release];
    }
}

0
2018-02-23 15:14