Получение строки ячейки UITableView при нажатии кнопки - PullRequest
84 голосов
/ 21 сентября 2011

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

Ответы [ 10 ]

278 голосов
/ 29 апреля 2013

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

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

Swift версия:

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

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

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

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

40 голосов
/ 21 сентября 2011

Редактировать: Этот ответ устарел. Пожалуйста, используйте этот метод вместо


Попробуйте:

-(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;
18 голосов
/ 18 октября 2013

Я бы порекомендовал этот способ получить indexPath ячейки с любым пользовательским подпредставлением - ( совместимо с 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, добавленный в ваше настраиваемое подпредставление.

3 голосов
/ 18 сентября 2012

Есть два способа:

  1. @ 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);
    }
    
  2. Если вы создаете пользовательский 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);
    }
    
2 голосов
/ 31 марта 2014

Другой простой способ:

  • Получить точку касания в 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
    // ...
}
2 голосов
/ 21 сентября 2011

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

1 голос
/ 16 марта 2017

Swift 3

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

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

Два второстепенных комментария:

  1. Функция по умолчанию имеет тип отправителя Any, для которого нет преобразования.
  2. CGPointZero можно заменить на CGPoint ()
0 голосов
/ 29 декабря 2017

В быстром:

@IBAction func buttonAction(_ sender: UIButton) {
    guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
        return
    }
    // do something
}
0 голосов
/ 25 июля 2016

Я хотел бы поделиться кодом в 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
    }
}
0 голосов
/ 21 сентября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...