セルからindexPath
をUITableView
に取得するにはどうすればよいですか?
スタックオーバーフローとグーグルを検索しましたが、すべての情報は逆になっています。 superView
/UITableView
にアクセスしてからセルを検索する方法はありますか?
コンテキストについての詳細:私が持っている2つのクラスがあり、1つはCue
と呼ばれ、もう1つはCueTableCell
(UITableViewCell
のサブクラス)と呼ばれますCueTableCell
はCue
の視覚的表現(両方のクラスは互いにポインターを持っています)。 Cue
オブジェクトはリンクリストにあり、ユーザーが特定のコマンドを実行するとき、次のCueTableCell
の視覚的表現(Cue
)を選択する必要があります。したがって、Cue
クラスは、リストの次のselect
でCue
メソッドを呼び出します。これは、UITableView
からcell
を取得し、そのselectRowAtIndexPath:animated:scrollPosition:
を呼び出します。 indexPath
のUITableViewCell
が必要です。
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
議論の余地があると考えられている場合でも、 ITableView documentation を読むのに役立ちます(以下のコメントを参照)。
セルには、インデックスパスが何であるかを把握しているビジネスはありません。 controllerには、データモデルに基づいてUI要素を操作したり、UIの相互作用に基づいてデータを変更したりするコードを含める必要があります。 ( MVC を参照してください。)
UITableViewCellからこれを試してください:
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
編集:これはiOS 8.1.2以降では動作しないようです。それを指摘してくれたクリスプリンスに感謝します。
この簡単なヒントを試すことができます:
UITableViewCell
クラスで:
@property NSInteger myCellIndex; //or add directly your indexPath
cellForRowAtIndexPath
メソッドで:
...
[cell setMyCellIndex : indexPath.row]
これで、どこでもセルインデックスを取得できます
次のように、セルの.hファイルに弱いtableViewプロパティを配置します。
@property (weak,nonatomic)UITableView *tableView;
CellForRowAtIndexメソッドでプロパティを次のように割り当てます。
cell.tableView = tableView;
セルのindexPathが必要な場合はどこでも:
NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];
"this is bad idea"と言う人に対応するために、私の場合、これが必要なのは、UITableViewCell
にボタンがあり、それを押すと別のビューにセグエになるということです。これはセル自体の選択ではないため、[self.tableView indexPathForSelectedRow]
は機能しません。
これには2つのオプションがあります。
NSFetchedResultsController
を持っているという点を無効にしますしない特にテーブルが長い場合、すべてのオブジェクトをメモリに保存したい。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;
}
追伸私の実際のコードはテーブルビューからこれらすべてにアクセスしますが、なぜ誰かがテーブルセルでこのようなことを直接したいのかという例を示しています。
Swiftの場合
let indexPath :NSIndexPath = (self.superview.superview as! UITableView).indexPathForCell(self)!
この質問に対する答えは、実際に私を大いに助けてくれました。
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
を使用しました
私の場合、sender
はUITableViewCell
であり、prepareForSegue
メソッドに由来します。
notにTableViewController
がありましたが、UITableView property outlet
があったため、これを使用しました
Cell
のタイトルを見つける必要があったため、そのindexPathを知る必要がありました。
これが誰にも役立つことを願っています!
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を返します。
これを試してください(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;
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)
}
}
}
それはすべて私を形成します。
宜しくお願いします。
UITableViewCellからこれを試してください:
NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];