iOS SDK дает нам «из коробки» два варианта настроить кнопку, которая будет показана при сдвиге UITableViewCell влево.
Первый вариант, доступный с первых версий и до наших дней, мало привлекателен для обычных кнопок, поскольку предназначен именно для «опасных» действий, ибо фон окрашивается системой в красный цвет и не поддается легкому изменению через публичный API.
- (NSString *)tableView:(nonnull UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { return @"Настроить"; }
Второй вариант, доступный с iOS 8, больше привлекает, поскольку есть возможность указать стиль кнопки (Destructive, Normal), а также в случае надобности установить конкретный цвет фона через backgroundColor.
- (NSArray<UITableViewRowAction *> *)tableView:(nonnull UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { UITableViewRowAction *configureAction; configureAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Настроить" handler:^(UITableViewRowAction * __nonnull action, NSIndexPath * __nonnull indexPath) { // handle }]; return @[ configureAction ]; }
Ни первый, ни второй варианты не дают возможности назначить иконку, что довольно неприятно.
Но мы всё равно попробуем что-нибудь сделать.
Попытка раз
UITableViewRowAction выглядит более богатым к настройке. Попробуем поставить ему backgroundColor с помощью patternImage:
UIImage *patternImage = [UIImage imageNamed:@"gear_compact"]; // 50x50 configureAction.backgroundColor = [UIColor colorWithPatternImage:patternImage];
Результат ожидаемо кривоват, но мы хотя бы получили иконку на кнопке.
Оставим вопрос цвета фона и текста на потом, сперва попробуем настроить саму иконку.
Попытка два
Поскольку patternImage призван повторяться, попробуем увеличить сам pattern, чтобы он повторялся поменьше — создадим pattern по размеру кнопки:
UIImage *patternImage = [UIImage imageNamed:@"gear_fullsize"]; // 240x90 configureAction.backgroundColor = [UIColor colorWithPatternImage:patternImage];
Теперь смотрится гораздо лучше. Но если, например, поле окажется многострочным, а следом по высоте растянется и ячейка, то будет не очень приятно:
Попытка три
Попробуем сделать иначе. Что происходит, когда мы сдвигаем строку влево? Верно, она просто уезжает левее, обнажая то, что находится ниже по иерархии: кнопку. Попробуем добавить слой сверху, который будет пристегнут к правому краю ячейки (компонент PureLayout в помощь для быстроты реализации).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [UITableViewCell new]; cell.textLabel.text = self.objects[indexPath.row]; cell.textLabel.numberOfLines = 0; UIView *actionView = [UIView new]; actionView.backgroundColor = [UIColor greenColor]; [cell addSubview:actionView]; [actionView autoMatchDimension:ALDimensionHeight toDimension:ALDimensionHeight ofView:cell]; [actionView autoMatchDimension:ALDimensionWidth toDimension:ALDimensionWidth ofView:cell]; [actionView autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:cell]; [actionView autoAlignAxis:ALAxisHorizontal toSameAxisOfView:cell.contentView]; UIImageView *actionIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gear_compact"]]; [actionView addSubview:actionIcon]; [actionIcon autoAlignAxis:ALAxisHorizontal toSameAxisOfView:actionView]; [actionIcon autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:actionView withOffset:10]; UILabel *actionLabel = [UILabel new]; actionLabel.text = @"Настроить"; [actionView addSubview:actionLabel]; [actionLabel autoAlignAxis:ALAxisHorizontal toSameAxisOfView:actionView]; [actionLabel autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:actionIcon withOffset:5]; return cell; }
Теперь результат гораздо приятнее, правда есть одно но в данном подходе: ширина сдвига ячейки определяется текстом в UITableViewRowAction.title. Соответственно, придется регулировать видимую часть кнопки именно этим параметром. Как вариант — заполнять его соответствующими нужной ширине пробелами, или дописывать что-то в начало или конец.
К слову, данный элемент не отрабатывает нажатия сам, поэтому они спокойно пересылаются в UITableViewRowAction.handler.
Попытка четыре
- (NSArray<UITableViewRowAction *> *)tableView:(nonnull UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { UITableViewRowAction *configureAction; configureAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"(i) Настроить" handler:^(UITableViewRowAction * __nonnull action, NSIndexPath * __nonnull indexPath) { // handle }]; return @[ configureAction ]; }
Похоже, теперь всё выглядит отлично.
В итоге есть два но при таком подходе:
— ширина сдвига определяется отдельно параметром UITableViewRowAction.title
— не получится сделать более одной кнопки, либо придется теснить их все в собственном слое и туда же вставлять свои кнопки
Однако это видится мне приятнее, чем распространенный подход по встраиванию кнопки в саму ячейку с обработкой жестов, поскольку усложняется логика.
Возможно, есть еще более лаконичный способ добиться желаемого, но мне о таком пока неизвестно.
ссылка на оригинал статьи http://habrahabr.ru/post/261905/
Добавить комментарий