web-dev-qa-db-ja.com

CellからUITableViewCell indexPathを取得する方法は?

セルからindexPathUITableViewに取得するにはどうすればよいですか?

スタックオーバーフローとグーグルを検索しましたが、すべての情報は逆になっています。 superView/UITableViewにアクセスしてからセルを検索する方法はありますか?

コンテキストについての詳細:私が持っている2つのクラスがあり、1つはCueと呼ばれ、もう1つはCueTableCellUITableViewCellのサブクラス)と呼ばれますCueTableCellCueの視覚的表現(両方のクラスは互いにポインターを持っています)。 Cueオブジェクトはリンクリストにあり、ユーザーが特定のコマンドを実行するとき、次のCueTableCellの視覚的表現(Cue)を選択する必要があります。したがって、Cueクラスは、リストの次のselectCueメソッドを呼び出します。これは、UITableViewからcellを取得し、そのselectRowAtIndexPath:animated:scrollPosition:を呼び出します。 indexPathUITableViewCellが必要です。

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

議論の余地があると考えられている場合でも、 ITableView documentation を読むのに役立ちます(以下のコメントを参照)。

セルには、インデックスパスが何であるかを把握しているビジネスはありません。 controllerには、データモデルに基づいてUI要素を操作したり、UIの相互作用に基づいてデータを変更したりするコードを含める必要があります。 ( MVC を参照してください。)

132
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]

これで、どこでもセルインデックスを取得できます

11
  1. 次のように、セルの.hファイルに弱いtableViewプロパティを配置します。

    @property (weak,nonatomic)UITableView *tableView;

  2. CellForRowAtIndexメソッドでプロパティを次のように割り当てます。

    cell.tableView = tableView;

  3. セルのindexPathが必要な場合はどこでも:

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

10
Chanchal Raj

"this is bad idea"と言う人に対応するために、私の場合、これが必要なのは、UITableViewCellにボタンがあり、それを押すと別のビューにセグエになるということです。これはセル自体の選択ではないため、[self.tableView indexPathForSelectedRow]は機能しません。

これには2つのオプションがあります。

  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

Swiftの場合

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

この質問に対する答えは、実際に私を大いに助けてくれました。

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];を使用しました

私の場合、senderUITableViewCellであり、prepareForSegueメソッドに由来します。

notTableViewControllerがありましたが、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にセクションが1つしかなく、すべてのセルの高さが等しい場合にのみ機能します):

//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

UITableViewCellからこれを試してください:

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