Подтвердить что ты не робот

Как я могу отслеживать путь указателя кнопки в ячейке таблицы?

У меня есть представление таблицы, где каждая ячейка имеет вид аксессуаров кнопки. Управление таблицей осуществляется с помощью выбранного контроллера результатов и часто переупорядочивается. Я хочу, чтобы можно было нажать одну из кнопок и получить индексный указатель этой ячейки таблицы кнопок. Я пытаюсь получить эту работу в течение нескольких дней, сохраняя строку кнопки в своем теге, но когда таблица переупорядочивается, строка становится некорректной, и я продолжаю терпеть неудачу при правильной настройке тегов. Любые новые идеи о том, как отслеживать путь указателя на ячейку?

4b9b3361

Ответ 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")

}