Получение строки ячейки UITableView при нажатии кнопки

У меня есть контроллер таблицы, который отображает строку ячеек. Каждая ячейка имеет 3 кнопки. Я пронумеровал теги для каждой ячейки равными 1,2,3. Проблема в том, что я не знаю, как найти, на какой ячейке нажата кнопка. В настоящее время я получаю только тег отправителя, когда была нажата одна из кнопок. Есть ли способ получить номер строки ячейки, когда нажата кнопка?

Ответ 1

Вместо этого вы должны использовать этот метод:

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

Быстрая версия:

let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)

Это даст вам indexPath в зависимости от положения кнопки, которая была нажата. Затем вы просто вызываете cellForRowAtIndexPath, если вам нужна ячейка или indexPath.row, если вам нужен номер строки.

Если вы параноик, вы можете проверить if (indexPath) ... перед тем, как использовать его, только если indexPath не найден для этой точки в представлении таблицы.

Все остальные ответы могут сломаться, если Apple решит изменить структуру представления.

Ответ 2

Изменить: этот ответ устарел. Используйте этот метод вместо


Попробуйте следующее:

-(void)button1Tapped:(id)sender
{
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    UITableView* table = (UITableView *)[buttonCell superview];
    NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
    NSInteger rowOfTheCell = [pathOfTheCell row];
    NSLog(@"rowofthecell %d", rowOfTheCell);
}

Изменить: если вы используете contentView, используйте вместо этого для buttonCell:

UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;

Ответ 3

Я бы порекомендовал этот способ получить индексную ячейку ячейки, которая имеет любое пользовательское подвью - (совместимое с iOS 7, а также со всеми предыдущими версиями)

-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
//    UIView *parentCell = gestureRecognizer.view.superview;
    UIView *parentCell = sender.superview;

    while (![parentCell isKindOfClass:[UITableViewCell class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentCell = parentCell.superview;
    }

    UIView *parentView = parentCell.superview;

    while (![parentView isKindOfClass:[UITableView class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentView = parentView.superview;
    }


    UITableView *tableView = (UITableView *)parentView;
    NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];

    NSLog(@"indexPath = %@", indexPath);
}

Для этого не требуется self.tablview.

Также обратите внимание на комментированный код, который полезен, если вы хотите, чтобы он с помощью @selector пользователя UIGestureRecognizer был добавлен в ваш пользовательский под просмотр.

Ответ 4

Существует два способа:

  • @H2CO3 является правильным. Вы можете сделать то, что предложил @user523234, но с небольшим изменением, уважать UITableViewCellContentView, который должен находиться между UIButton и UITableViewCell. Поэтому, чтобы изменить его код:

    - (IBAction)button1Tapped:(id)sender
    {
        UIButton *senderButton = (UIButton *)sender;
        UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
        UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
        UITableView* tableView = (UITableView *)tableViewCell.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    
  • Если вы создаете пользовательский UITableViewCell (ваш собственный подкласс), вы можете просто вызвать self в IBAction. Вы можете связать функцию IBAction с вашей кнопкой, используя раскадровку или программно, когда вы настроите ячейку.

    - (IBAction)button1Tapped:(id)sender
    {
        UITableView* tableView = (UITableView *)self.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    

Ответ 5

Я предполагаю, что вы добавляете кнопки в ячейку в cellForRowAtIndexPath, тогда я бы сделал, чтобы создать пользовательский класс-подкласс UIButton, добавить тег , называемый rowNumber, и добавить эти данные пока вы добавляете кнопку в ячейку.

Ответ 6

Еще один простой способ:

  • Получите осязание в tableView

  • Затем введите индексный путь ячейки в точке

  • Путь индекса содержит индекс строки

Код:

- (void)buttonTapped:(id)sender {
    UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
    CGPoint point = [tap locationInView:theTableView];

    NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];

    NSInteger theRowIndex = theIndexPath.row;
    // do your stuff here
    // ...
}

Ответ 7

Swift 3

Примечание. Это должно действительно идти в принятом ответе выше, за исключением того, что мета хмурится при таких изменениях.

@IBAction func doSomething(_ sender: UIButton) {
   let buttonPosition = sender.convert(CGPoint(), to: tableView)
   let index = tableView.indexPathForRow(at: buttonPosition)
}

Два небольших комментария:

  • Функция по умолчанию имеет тип отправителя как Any, у которого нет конвертирования.
  • CGPointZero может быть заменен на CGPoint()

Ответ 8

Одним из решений может быть проверка тега надстройки кнопок или даже выше в иерархии представлений (если кнопка находится в представлении содержимого ячейки).

Ответ 9

Я хотел бы поделиться кодом в swift -

extension UITableView
{
    func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
    {
        var view = view1;
        while view != nil {
            if (view?.isKindOfClass(UITableViewCell) == true)
            {
                return self.indexPathForCell(view as! UITableViewCell)!
            }
            else
            {
                view = view?.superview;
            }
        }
        return nil
    }
}

Ответ 10

Быстро:

@IBAction func buttonAction(_ sender: UIButton) {
    guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
        return
    }
    // do something
}