[英]IOS 7 - How to get the indexPath from button placed in UITableViewCell
[英]How to get UITableViewCell indexPath from the Cell?
我如何从单元格中获取UITableView
indexPath
?
我搜索了堆栈溢出和谷歌,但所有信息都在相反的方向。 有没有办法访问superView
/ UITableView
然后搜索单元格?
关于上下文的更多信息:我有两个类,一个叫做Cue
,一个叫做CueTableCell
(它是UITableViewCell
的子类) CueTableCell
是Cue
的可视化表示(两个类都有彼此的指针)。 Cue
对象在一个链表中,当用户执行某个命令时,需要选择下一个Cue
的可视化表示( CueTableCell
)。 因此, Cue
类调用列表中下一个Cue
的select
方法,该方法从cell
检索UITableView
并调用其selectRowAtIndexPath:animated:scrollPosition:
,为此它需要UITableViewCell
的indexPath
。
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
它有助于阅读UITableView 文档,即使有人认为这是有争议的(请参阅下面的评论)。
单元不知道它的索引路径是什么。 控制器应包含任何基于数据模型操作 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]
现在,您可以在任何地方检索您的单元格索引
为了解决那些说“这是一个坏主意”的人,在我的情况下,我需要的是我的UITableViewCell
上有一个按钮,当按下时,它是另一个视图的转场。 由于这不是单元格本身的选择,因此[self.tableView indexPathForSelectedRow]
不起作用。
这给我留下了两个选择:
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;
}
PS 我的真实代码确实从表格视图访问了所有这些,但我举了一个例子,说明为什么有人可能想直接在表格单元格中做这样的事情。
在单元格的 .h 文件中放置一个弱 tableView 属性,例如:
@property (weak,nonatomic)UITableView *tableView;
在 cellForRowAtIndex 方法中分配属性,如:
cell.tableView = tableView;
现在,无论您在哪里需要单元格的 indexPath:
NSIndexPath *indexPath = [cell.tableView indexPathForCell:cell];
为迅捷
let indexPath :NSIndexPath? = (self.superview.superview as! UITableView)?.indexPathForCell(self)
这个问题的答案实际上对我帮助很大。
我用NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
在我的例子中, sender
是一个UITableViewCell
并且来自prepareForSegue
方法。
我用这个,因为我没有一个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 只有一个部分并且所有单元格具有相同的高度):
//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 3.0 及以上-
如果需要从自定义单元格中获取索引路径 -
if let tableView = self.superview as? UITableView{
if let indexPath = tableView.indexPath(for: self){
print("Indexpath acquired.")
}else{
print("Indexpath could not be acquired from tableview.")
}
}else{
print("Superview couldn't be cast as tableview")
}
最好的做法是注意失败案例。
从你的 UITableViewCell 试试这个:
NSIndexPath *indexPath = [(UITableView *)self.superview.superview indexPathForCell:self];
斯威夫特 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)
}
}
}
这就是我的全部。
最好的祝福。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.