Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

Множественное выделение строк в UITableView

Как реализовать multi-selection в UITableView?


Ответ

По умолчанию, UITableView поддерживает режим выбора только одной строки. Но можно создать свой multi-selection в UITbaleView. Чтобы таблица имела возможность множественного выбора нужно поставить стиль стандартного выделения "none" и самостоятельно отслеживать события и менять вид элементов. Для этого следует выполнить несколько шагов: Пусть на верхней панели таблицы есть кнопка "Edit", которая при переходе в edit-mode меняется на "Cancel". При переходе в режим редактирования снизу таблицы появляется панель инструментов с вариантами действий над элементами таблицы. Для обнаружения выделенных строк использовать метод tableView:didSelectRowAtIndexPath:. В этом методе мы будем добавлять только что выбранный элемент в коллекцию. Т.к. мы не можем полагаться на стандартный UITableView, мы должны создать коллекцию, содержащую выделенные в данный момент элементы. Также, при выборе элемента мы должны сменить фон элемента и отодвинуть его от левого края, чтобы поместить туда специальный индикатор выделения (наподобие checkbox). Панель инструментов нужно создать в методе viewDidLoad, добавив что-то подобное: actionToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 416, 320, 44)]; actionButton = [[[UIBarButtonItem alloc] initWithTitle:@"No Action" style:UIBarButtonItemStyleBordered target:self action:@selector(noAction:)] autorelease]; [actionToolbar setItems:[NSArray arrayWithObject:actionButton]]; Затем, в методе viewDidAppear мы можем добавить нашу панель инструментов в иерархию - (void)viewDidAppear:(BOOL)animated { [self.view.superview addSubview:actionToolbar]; } Стандартный режим редактирования для UITableView реализуется посредством вызова setEditing:animated:. Но т.к. Мы не собираемся использовать никакой из стандартных UITableViewCellEditingStyle, то вызов этого метода не является строго обязательным, но его можно будет использовать для уведомления UITableViewCell. Методы edit и cancel можно реализовать примерно так: - (void)edit:(id)sender { [self showActionToolbar:YES]; UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(cancel:)] autorelease]; [self.navigationItem setRightBarButtonItem:cancelButton animated:NO]; [self updateSelectionCount]; [self.tableView setEditing:YES animated:YES]; }
- (void)cancel:(id)sender { [self showActionToolbar:NO]; UIBarButtonItem *editButton = [[[UIBarButtonItem alloc] initWithTitle:@"Edit" style:UIBarButtonItemStylePlain target:self action:@selector(edit:)] autorelease]; [self.navigationItem setRightBarButtonItem:editButton animated:NO]; NSInteger row = 0; for (MultiSelectCellController *cellController in [tableGroups objectAtIndex:0]) { [cellController clearSelectionForTableView:self.tableView indexPath:[NSIndexPath indexPathForRow:row inSection:0]]; row++; } [self.tableView setEditing:NO animated:YES]; } Далее, при вызове setEditing у UITableView таблица вызывает setEditing у всех видимых элементов (UITableViewCell). Мы можем переопределить этот метод и использовать для перехода из режима в режим отдельно взятого элемента таблицы (показать или скрыть "галочку"). Проще всего это реализовать следующим образом: конкретно в методе setEditing мы инициируем relayout методом setNeedsLayout, а основной код поместим в layoutSubviews (теперь мы будем правильно перерисовывать элемент вне зависимости от того, что стало причиной перерисовки). - (void)setEditing:(BOOL)editing animated:(BOOL)animated { [self setNeedsLayout]; } Можно непосредственно в layoutSubviews и добавлять сам рисунок "галочки". Но с точки зрения организации кода это не очень красивое решение, т.к. подразумевается, что UITableViewCell - это только макет элемента. Поэтому лучше добавлять галочку уже в UITableView, но это неважно. Итак, в layoutSubviews мы будем отодвигать элемент от левого края, чтобы освободить место для "галочки", вот так: - (void)layoutSubviews { [UIView beginAnimations:nil context:nil]; [UIView setAnimationBeginsFromCurrentState:YES]; [super layoutSubviews]; if (((UITableView *)self.superview).isEditing) { CGRect contentFrame = self.contentView.frame; contentFrame.origin.x = 40; // делаем отступ self.contentView.frame = contentFrame; } else { CGRect contentFrame = self.contentView.frame; contentFrame.origin.x = 0; self.contentView.frame = contentFrame; } [UIView commitAnimations]; } Теперь осталось только поставить cell.selectionStyle = UITableViewCellSelectionStyleNone т.к. мы не хотим использовать стандартный selection. Вместо этого надо просто менять backgroundView у элемента. P.s. Пример можно посмотреть в приложении Mail.

Комментариев нет:

Отправить комментарий