Подтвердить что ты не робот

Использование строк вставки в UITableView

Я бы хотел, чтобы мой UITableView вел себя как таблица в редакторе контактов, то есть пользователь должен нажать "Изменить", а строка "добавить новую категорию" должна появиться внизу каждого раздела.

Я использую приведенный ниже код для этого, но проблема в том, что плавный переход не происходит, как в "Контакты". Вместо этого появляется новая строка. Как я могу получить анимацию?

Также, как мне реагировать на клики по строке "добавить новую категорию"? Строка не может быть нажата в моей текущей реализации.

Нужно ли перезагружать данные, когда пользователь начинает редактирование? Я делаю это, потому что иначе строки вставки никогда не рисуются.

Спасибо.

- (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;
}
4b9b3361

Ответ 1

Мне не хватало одной вещи. В setEditing: вместо вызова reloadData я должен был сделать:

- (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];
}

Ответ 2

Ответ на клики по строке может быть выполнен в методе didSelectRowAtIndexPath для indexPath.row == [items count]. Для анимации я предлагаю посмотреть здесь, по методу insertRowsAtIndexPaths:withRowAnimation:. Там есть сообщение о том, как его использовать здесь.

Ответ 3

Нежелательным побочным эффектом выделенного решения является то, что строка "добавить" также вставлена ​​также, когда пользователь просто просматривает одну строку (при условии, что проверка включена). Следующий дилемма решает эту проблему:

// 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;
}

Для вашего кода потребуется небольшое изменение:

- (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];
    }
}