Использование строк вставки в 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;
}
Ответы
Ответ 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];
}
}