it-roy-ru.com

Как получить UITableViewCell indexPath из ячейки?

Как из ячейки получить indexPath в UITableView?

Я искал вокруг переполнения стека и Google, но вся информация наоборот. Есть ли какой-нибудь способ получить доступ к superView/UITableView и затем выполнить поиск ячейки?

Больше информации о контексте: у меня есть два класса, один называется Cue, а другой называется CueTableCell (который является подклассом UITableViewCell) CueTableCell - это визуальное представление Cue (оба класса имеют указатели друг на друга). Объекты Cue находятся в связанном списке, и когда пользователь выполняет определенную команду, необходимо выбрать визуальное представление (CueTableCell) следующего Cue. Таким образом, класс Cue вызывает метод select для следующего Cue в списке, который извлекает UITableView из cell и вызывает его selectRowAtIndexPath:animated:scrollPosition:, для которого ему требуется indexPathUITableViewCell.

63
sinθ
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

Это помогает читать документацию , даже если это считается спорным (см. Комментарии ниже).

Ячейка не имеет бизнеса, зная, каков ее индексный путь. Controller должен содержать любой код, который манипулирует элементами пользовательского интерфейса на основе модели данных или изменяет данные на основе взаимодействий пользовательского интерфейса. (См. MVC .)

126
Mundi

Попробуйте с этим из вашего UITableViewCell: 

NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];

Правка: Кажется, это не работает на iOS 8.1.2 и далее. Спасибо Крису Принсу за указание на это. 

25
Pepper

Вы можете попробовать этот простой совет: 

в вашем классе UITableViewCell

@property NSInteger myCellIndex; //or add directly your indexPath 

и на ваш метод cellForRowAtIndexPath:

...
[cell setMyCellIndex : indexPath.row]

теперь вы можете получить свой индекс клетки в любом месте

10
AITAALI_ABDERRAHMANE
  1. Поместите слабое свойство tableView в файл .h ячейки, например:

    @property (weak,nonatomic)UITableView *tableView;

  2. Назначьте свойство в методе cellForRowAtIndex, например:

    cell.tableView = tableView;

  3. Теперь везде, где вам нужен indexPath ячейки:

    NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];

10
Chanchal Raj

Чтобы обратиться к тем, кто говорит «это плохая идея», в моем случае мне нужно это, чтобы у меня на кнопке UITableViewCell была кнопка, которая при нажатии вызывает переход к другому виду. Поскольку это не выборка самой ячейки, [self.tableView indexPathForSelectedRow] не работает.

Это оставляет мне два варианта:

  1. Сохранить объект, который мне нужно передать в представление в самой ячейке таблицы. Хотя это будет работать, это лишит меня смысла в наличии NSFetchedResultsController, потому что я не хочу хранить все объекты в памяти, особенно если таблица длинная.
  2. Получить элемент из контроллера выборки, используя путь индекса. Да, кажется уродливым, что я должен разобраться с NSIndexPath взломом, но это в конечном итоге дешевле, чем хранение объектов в памяти.

indexPathForCell: - правильный метод для использования, но вот как я бы это сделал (предполагается, что этот код реализован в подклассе UITableViewCell:

// uses the indexPathForCell to return the indexPath for itself
- (NSIndexPath *)getIndexPath {
    return [[self getTableView] indexPathForCell:self];
}

// retrieve the table view from self   
- (UITableView *)getTableView {
    // get the superview of this class, note the camel-case V to differentiate
    // from the class' superview property.
    UIView *superView = self.superview;

    /*
      check to see that *superView != nil* (if it is then we've walked up the
      entire chain of views without finding a UITableView object) and whether
      the superView is a UITableView.
    */
    while (superView && ![superView isKindOfClass:[UITableView class]]) {
        superView = superView.superview;
    }

    // if superView != nil, then it means we found the UITableView that contains
    // the cell.
    if (superView) {
        // cast the object and return
        return (UITableView *)superView;
    }

    // we did not find any UITableView
    return nil;
}

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

9
mikeho

Для Свифта 

let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)!
6
Gevorg Ghukasyan

Ответ на этот вопрос мне очень помог.

Я использовал NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

sender в моем случае был UITableViewCell и происходит от метода prepareForSegue.

Я использовал это, потому что у меня нет есть TableViewController, но у меня был UITableView property outlet

Мне нужно было узнать заголовок Cell и, следовательно, нужно было узнать его indexPath.

Надеюсь, это кому-нибудь поможет!

4
Cescy

На iOS 11.0 вы можете использовать UITableView.indexPathForRow(at point: CGPoint) -> IndexPath?:

if let indexPath = tableView.indexPathForRow(at: cell.center) {
    tableView.selectRow
    (at: indexPath, animated: true, scrollPosition: .middle)
}

Он получает центральную точку ячейки, а затем tableView возвращает indexPath, соответствующий этой точке. 

2
banan3'14

попробуйте это (это работает только если tableView имеет только один раздел и все ячейки имеют одинаковую высоту):

//get current cell rectangle relative to its superview
CGRect r = [self convertRect:self.frame toView:self.superview];

//get cell index
int index = r.Origin.y / r.size.height;
1
m.eldehairy

Swift 4.x

Чтобы обеспечить доступ к моей камере, я сделал что-то вроде этого:

У меня есть расширение UIView:

extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}

А потом .. в моей камере Класс:

class SomeCell: UITableViewCell {

    func someMethod() {
        if let myViewController = self.parentViewController as? CarteleraTableViewController {
            let indexPath : IndexPath = (myViewController.tableView).indexPath(for: self)!
            print(indexPath)
        }
    }
}

Это все формирует меня.

С наилучшими пожеланиями.

0
LagMaster

Попробуйте с этим из вашего UITableViewCell:

NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];
0
Yogesh Kumar