У меня есть представление таблицы, где каждая ячейка имеет вид аксессуаров кнопки. Управление таблицей осуществляется с помощью выбранного контроллера результатов и часто переупорядочивается. Я хочу, чтобы можно было нажать одну из кнопок и получить индексный указатель этой ячейки таблицы кнопок. Я пытаюсь получить эту работу в течение нескольких дней, сохраняя строку кнопки в своем теге, но когда таблица переупорядочивается, строка становится некорректной, и я продолжаю терпеть неудачу при правильной настройке тегов. Любые новые идеи о том, как отслеживать путь указателя на ячейку?
Как я могу отслеживать путь указателя кнопки в ячейке таблицы?
Ответ 1
Я создал один метод для получения indexPath, надеюсь, это вам поможет.
Создать действие кнопки (aMethod:) в cellForRowAtIndexPath
-(void) aMethod:(UIButton *)sender
{
// Calling Magic Method which will return us indexPath.
NSIndexPath *indexPath = [self getButtonIndexPath:sender];
NSLog(@"IndexPath: %li", indexPath.row);
NSLog(@"IndexRow: %li", indexPath.section);
}
//Вот волшебный метод для получения кнопки indexPath
-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}
Ответ 2
Если вам неудобно полагаться на button.superview
, этот метод должен быть немного более надежным, чем некоторые другие ответы здесь:
UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
Ответ 3
Это перестало работать с iOS 7; проверьте ответ Майка Веллера вместо этого
- (IBAction)clickedButton:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview;
UITableView *tableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}
Или короче:
- (IBAction)clickedButton:(id)sender {
NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}
Оба непроверены!
Ответ 4
Искажения сканирования с помощью .superview
(как показывают все существующие ответы) - это действительно плохой способ сделать что-то. Если структура UITableViewCell
изменится (что произошло раньше), ваше приложение сломается. Увидев .superview.superview
в вашем коде, следует отключить звуковые сигналы.
Кнопка и ее обработчик должны быть добавлены в пользовательский подкласс UITableViewCell
и выложены там. То, где оно принадлежит.
Подкласс ячейки может затем делегировать событие кнопки через стандартный интерфейс делегата или блок. Вы должны стремиться к чему-то вроде этого:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = ...;
// ...
cell.onButtonTapped = ^{
[self buttonSelectedAtIndexPath:indexPath];
}
// OR
cell.delegate = self;
// ...
}
(Примечание: если вы идете по блочному маршруту, вам нужно будет использовать ссылку __weak
для предотвращения циклов сохранения, но я думал, что это загромождает пример).
Если вы возьмете маршрут делегата, вы должны реализовать этот метод делегата:
- (void)cellButtonPressed:(UITableViewCell *)cell
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// ...
}
Теперь ваш код имеет полный доступ к соответствующему контексту, когда он обрабатывает событие.
Реализация этого интерфейса в вашем классе ячейки должна быть простой.
Ответ 5
Я не знаю, почему мне нужно дважды вызвать метод superview, чтобы получить UITableViewCell.
Update:
Спасибо за Qiulang, теперь я получил его.
"Это потому, что SDK теперь добавил частный класс под названием UITableViewCellContentView для UITableViewCell, который теперь просматривает кнопки." - Цюлан
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
Ответ 6
У меня тоже была эта проблема, и был создан простой рекурсивный метод, который работает независимо от того, сколько представлений, которые вы запускаете, контролирует.
-(NSIndexPath*)GetIndexPathFromSender:(id)sender{
if(!sender) { return nil; }
if([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *cell = sender;
return [self.tableView indexPathForCell:cell];
}
return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}
-(void)ButtonClicked:(id)sender{
NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}
Ответ 7
Используйте это Perfect для меня.
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);
Ответ 8
ОБНОВЛЕНИЕ SWIFT 2
Здесь, как узнать, какая кнопка была нажата
@IBAction func yourButton(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
print("Tap tap tap tap")
}