Шрифт:
Интервал:
Закладка:
Как объяснялось ранее, табличный вид инициирует события, направляемые его объекту-делегату. Кнопка детализации из табличного вида также запускает событие, которое может быть принято объектом-делегатом табличного вида:
— (void) tableView:(UITableView *)tableView
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
/* Делаем что-либо при нажатии дополнительной кнопки. */
NSLog(@"Accessory button is tapped for cell at index path = %@",
indexPath);
UITableViewCell *ownerCell = [tableView cellForRowAtIndexPath: indexPath];
NSLog(@"Cell Title = %@", ownerCell.textLabel.text);
}
Данный код ищет ячейку табличного вида, в которой была нажата кнопка детализации, и выводит в окне консоли содержимое текстовой метки данной ячейки. Напоминаю: чтобы отобразить окно консоли в Xcode, нужно выполнить команду RunConsole (ЗапускКонсоль).
4.3. Создание специальных дополнительных элементов в ячейке табличного вида
Постановка задачи
Дополнительных элементов, предоставляемых в iOS, недостаточно для решения задачи, и вы хотели бы создать собственные дополнительные элементы.
Решение
Присвойте экземпляр класса UIView свойству accessoryView любого экземпляра класса UITableViewCell:
— (UITableViewCell *) tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier: MyCellIdentifier
forIndexPath: indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"Section %ld, Cell %ld",
(long)indexPath.section,
(long)indexPath.row];
UIButton *button = [UIButton buttonWithType: UIButtonTypeSystem];
button.frame = CGRectMake(0.0f, 0.0f, 150.0f, 25.0f);
[button setTitle:@"Expand"
forState: UIControlStateNormal];
[button addTarget: self
action:@selector(performExpand:)
forControlEvents: UIControlEventTouchUpInside];
cell.accessoryView = button;
return cell;
}
Как видите, в этом коде используется метод performExpand:. Он играет роль селектора для каждой кнопки. Вот определение данного метода:
— (void) performExpand:(id)paramSender{
/* Обрабатываем событие нажатия кнопки */
}
В данном примере кода специальная создаваемая нами кнопка присваивается дополнительному виду в каждой строке выбранной таблицы. Результат показан на рис. 4.4.
Рис. 4.4. Ячейки табличного вида со специальными дополнительными видами
Обсуждение
Объект типа UITableViewCell содержит свойство accessoryView. Это тот вид, которому вы можете присвоить значение, если вас не вполне устраивают встроенные в SDK iOS дополнительные виды для табличных ячеек. После того как задано это свойство, Cocoa Touch будет игнорировать значение свойства accessoryType и станет использовать вид, присвоенный свойству accessoryView, в качестве дополнительного элемента, который отображается в ячейке таблицы.
В коде, приведенном в подразделе «Решение» данного раздела, мы создаем кнопки для всех ячеек, находящихся в табличном виде. При нажатии кнопки в любой ячейке вызывается метод performExpand:. И если вы думаете примерно так же, как я, то вы уже стали задаваться вопросом: как же определить, к какой именно ячейке относится кнопка-отправитель? Итак, теперь нам нужно как-то связать кнопки с теми ячейками, к которым они относятся.
Один из способов разрешения этой ситуации связан с использованием свойства tag экземпляра кнопки. Это свойство-метка представляет собой обычное целое число, которое, как правило, используется для ассоциирования вида с другим объектом. Например, если вы хотите ассоциировать кнопку с третьей ячейкой в вашем табличном виде, то следует задать для свойства-метки этой кнопки значение 3. Но здесь возникает проблема: в табличных видах есть разделы, и каждый раздел может содержать n ячеек. Следовательно, нам требуется возможность определить и раздел таблицы, и ячейку, которая владеет нашей кнопкой. А поскольку значением свойства-метки может быть только одно целое число, эта задача существенно усложняется. Поэтому мы можем отказаться от метки и вместо работы с ней запрашивать вышестоящий вид о дополнительном виде, рекурсивно проходя вверх по цепочке видов, пока не найдем ячейку типа UITableViewCell, вот так:
— (UIView *) superviewOfType:(Class)paramSuperviewClass
forView:(UIView *)paramView{
if (paramView.superview!= nil){
if ([paramView.superview isKindOfClass: paramSuperviewClass]){
return paramView.superview;
} else {
return [self superviewOfType: paramSuperviewClass
forView: paramView.superview];
}
}
return nil;
}
— (void) performExpand:(UIButton *)paramSender{
/* Обрабатываем событие нажатия кнопки */
__unused UITableViewCell *parentCell =
(UITableViewCell *)[self superviewOfType: [UITableViewCell class]
forView: paramSender];
/* Теперь, если желаете, можете еще что-нибудь сделать с ячейкой */
}
Здесь мы используем простой рекурсивный метод, принимающий вид (в данном случае нашу кнопку) и имя класса (в данном случае UITableViewCell), а затем просматриваем иерархию вида, являющегося вышестоящим для данного, чтобы найти вышестоящий вид, относящийся к интересующему нас классу. Итак, он начинает работу с вида, являющегося вышестоящим для заданного, и если этот вышестоящий вид не относится к требуемому типу, то просматривает и его вышестоящий вид, и так до тех пор, пока не найдет один из вышестоящих видов, относящийся к требуемому классу. Как видите, в качестве первого параметра метода superviewOfType: forView: мы используем структуру Class. В этом типе данных может содержаться имя любого класса из языка Objective-C, и это весьма кстати, если вы ищете или запрашиваете у программиста конкретные имена классов.
4.4. Обеспечение удаления смахиванием в ячейках табличных видов
Постановка задачи
Необходимо предоставить пользователям приложения возможность без труда удалять строки из табличного вида.
Решение
Реализуйте в делегате табличного вида селектор tableView: editingStyleForRowAtIndexPath:, а в источнике данных табличного вида — селектор tableView: commitEditingStyle: forRowAtIndexPath::
— (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete;
}
— (void) setEditing:(BOOL)editing
animated:(BOOL)animated{
[super setEditing: editing
animated: animated];
[self.myTableView setEditing: editing
animated: animated];
}
— (void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete){
/* Сначала удаляем этот объект из источника данных */
[self.allRows removeObjectAtIndex: indexPath.row];
/* Потом удаляем ассоциированную с ним ячейку из табличного вида */
[tableView deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation: UITableViewRowAnimationLeft];
}
}
Метод tableView: editingStyleForRowAtIndexPath: позволяет выполнять операции удаления. Он вызывается табличным видом, а его возвращаемое значение определяет, какие операции пользователь может делать в табличном виде (вставлять информацию, удалять информацию и т. д.). Метод tableView: commitEditingStyle: forRowAtIndexPath: выполняет затребованную пользователем операцию удаления. Второй из указанных методов определяется в делегате, но его функционал несколько перегружен: этот метод применяется не только для удаления данных, но и для удаления строк из таблицы.
Обсуждение
Табличный вид реагирует на жест смахивания (Swipe), отображая кнопку в правой части затронутой строки (рис. 4.5). Как видите, табличный вид не находится в режиме редактирования, но эта кнопка позволяет пользователю удалить строку.
Рис. 4.5. Кнопка для удаления, появляющаяся в ячейке табличного вида
Такой режим активизируется путем реализации метода tableView: editingStyleForRowAtIndexPath: (определяемого в протоколе UITableViewDelegate), чье возвращаемое значение указывает, будут ли в таблице разрешаться операции вставки, или удаления, или обе эти операции, или ни одна из них. Реализуя метод tableView: commitEditingStyle: forRowAtIndexPath: в источнике данных табличного вида, можно также получать уведомление о том, какую операцию выполнил пользователь, вставку или удаление.
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- Стандарты программирования на С++. 101 правило и рекомендация - Герб Саттер - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Генерация высококачественного кода для программ, написанных на СИ - Филипп Хислей - Программирование
- Программирование на Python с нуля - Максим Кононенко - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика