如何在元素被激活时获取 indexpath.row? [英] How to get the indexpath.row when an element is activated?
问题描述
我有一个带按钮的 tableview,我想在点击其中一个按钮时使用 indexpath.row.这是我目前拥有的,但始终为 0
I have a tableview with buttons and I want to use the indexpath.row when one of them is tapped. This is what I currently have, but it always is 0
var point = Int()
func buttonPressed(sender: AnyObject) {
let pointInTable: CGPoint = sender.convertPoint(sender.bounds.origin, toView: self.tableView)
let cellIndexPath = self.tableView.indexPathForRowAtPoint(pointInTable)
println(cellIndexPath)
point = cellIndexPath!.row
println(point)
}
推荐答案
giorashc 在他的回答中几乎得到了它,但他忽略了单元格有一个额外的 contentView
层这一事实.因此,我们必须更深入一层:
giorashc almost had it with his answer, but he overlooked the fact that cell's have an extra contentView
layer. Thus, we have to go one layer deeper:
guard let cell = sender.superview?.superview as? YourCellClassHere else {
return // or fatalError() or whatever
}
let indexPath = itemTable.indexPath(for: cell)
这是因为在视图层次结构中,tableView 具有作为子视图的单元格,这些单元格随后具有自己的内容视图",这就是为什么您必须获取此内容视图的超级视图才能获取单元格本身.因此,如果您的按钮包含在子视图中,而不是直接包含在单元格的内容视图中,则您必须深入到更深的多层才能访问它.
This is because within the view hierarchy a tableView has cells as subviews which subsequently have their own 'content views' this is why you must get the superview of this content view to get the cell itself. As a result of this, if your button is contained in a subview rather than directly into the cell's content view, you'll have to go however many layers deeper to access it.
以上是一种这样的方法,但不一定是最好的方法.虽然它是功能性的,但它假定了关于 UITableViewCell
的细节,Apple 从未必要记录过这些细节,例如它的视图层次结构.这在未来可能会改变,结果上面的代码很可能会出现不可预测的行为.
The above is one such approach, but not necessarily the best approach. Whilst it is functional, it assumes details about a UITableViewCell
that Apple have never necessarily documented, such as it's view hierarchy. This could be changed in the future, and the above code may well behave unpredictably as a result.
由于上述原因,出于使用寿命和可靠性的原因,我建议采用另一种方法.此线程中列出了许多替代方案,我鼓励您向下阅读,但我个人最喜欢的如下:
As a result of the above, for longevity and reliability reasons, I recommend adopting another approach. There are many alternatives listed in this thread, and I encourage you to read down, but my personal favourite is as follows:
在您的单元格类上保留一个闭包的属性,让按钮的操作方法调用它.
Hold a property of a closure on your cell class, have the button's action method invoke this.
class MyCell: UITableViewCell {
var button: UIButton!
var buttonAction: ((Any) -> Void)?
@objc func buttonPressed(sender: Any) {
self.buttonAction?(sender)
}
}
然后,当您在 cellForRowAtIndexPath
中创建单元格时,您可以为闭包分配一个值.
Then, when you create your cell in cellForRowAtIndexPath
, you can assign a value to your closure.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! MyCell
cell.buttonAction = { sender in
// Do whatever you want from your button here.
}
// OR
cell.buttonAction = buttonPressed(closure: buttonAction, indexPath: indexPath) // <- Method on the view controller to handle button presses.
}
通过将处理程序代码移到此处,您可以利用已经存在的 indexPath
参数.这是一种比上面列出的方法更安全的方法,因为它不依赖于未记录的特征.
By moving your handler code here, you can take advantage of the already present indexPath
argument. This is a much safer approach that the one listed above as it doesn't rely on undocumented traits.
这篇关于如何在元素被激活时获取 indexpath.row?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!