按下按钮时,是否在UITableViewCell中查找按钮的indexPath?
下面的代码正确返回单元格:按下按钮时,是否在UITableViewCell中查找按钮的indexPath?,uitableview,swift,uibutton,Uitableview,Swift,Uibutton,下面的代码正确返回单元格: func findSuperView(sender:UIButton!) -> UITableViewCell { var superView : UIView? = sender.superview var foundSuperView : UITableViewCell! while superView != nil && foundSuperView == nil { if let cell
func findSuperView(sender:UIButton!) -> UITableViewCell {
var superView : UIView? = sender.superview
var foundSuperView : UITableViewCell!
while superView != nil && foundSuperView == nil {
if let cell = superView as? UITableViewCell {
foundSuperView = cell
break
}
else {
superView = superView?.superview
}
}
return foundSuperView
}
但在tableview中查找indexpath会崩溃:
var indexPath : NSIndexPath = self.table .indexPathForCell(findSuperView(sender))!
println("Section (indexPath)")
我尝试了另一种方法,但没有成功:
var button : UIButton = sender as UIButton;
var touch: UITouch = events .allTouches()?.anyObject() as UITouch
var location : CGPoint = touch.locationInView(self.table)
var indexPath : NSIndexPath = self.table.indexPathForRowAtPoint(location)!
我不知道是否有一个简单的方法来做到这一点。(Edit:实际上有。看看@mustafa的第二个解决方案。)一个解决方法是在
cellforrowatinexpath
中将按钮的标记设置为indexPath.row
,然后您就可以访问按钮的标记,找出它属于哪一行
警告:此解决方案很脆弱。如果允许在不调用
tableView.reloadData()
的情况下从表中添加或删除行,则无法正常工作。看看@mustafa的解决方案,它更加健壮。func findSuperView(发送方:UIButton!)->UITableViewCell有一个问题。没有任何东西可以确保foundSuperView
具有值
func findSuperView(sender:UIButton!) -> UITableViewCell {
var superView : UIView? = sender.superview
var foundSuperView : UITableViewCell! // NOTE: The value is nil.
while superView != nil && foundSuperView == nil {
if let cell = superView as? UITableViewCell {
foundSuperView = cell
break
}
else {
superView = superView?.superview
}
}
return foundSuperView // NOTE: This will crash if foundSuperView == nil
}
查找视图的超级单元格的更安全的方法是返回可选的
func findSuperCellOfView(view: UIView?) -> UITableViewCell? {
if view == nil {
return nil
} else if let cell = view as? UITableViewCell {
return cell
} else {
return findSuperCellOfView(view?.superview)
}
}
将按如下方式使用
if let cell = findSuperCellOfView(button) {
let indexPath = table.indexPathForCell(cell)
println("Section \(indexPath)")
}
下面是按钮的
触碰内部事件的候选操作方法
func someAction(sender:UIButton, event: UIEvent) {
if let touch = event.touchesForView(sender)?.anyObject() as? UITouch {
let point = touch.locationInView(tableView)
if let indexPath = tableView.indexPathForRowAtPoint(point) {
// Do something with indexPath
}
}
}
还有一个:
func someAction(sender: UIButton) {
let point = tableView.convertPoint(CGPointZero, fromView: sender)
if let indexPath = tableView.indexPathForRowAtPoint(point) {
// Do something with indexPath
}
}
您似乎很难从处理按钮的@IBAction
的代码中找到tableView
您可以创建一个UIButton
子类来跟踪按钮所在的单元格和单元格所在的UITableView
。然后,只需在@IBAction
中调用按钮的tableView:indexPathForCell
MyButton.swift:
class MyButton: UIButton {
weak var myTable: UITableView?
weak var myCell: UITableViewCell?
}
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var myButton: MyButton!
@IBAction func whereAmI(button: MyButton) {
if let myCell = button.myCell, indexPath = button.myTable?.indexPathForCell(myCell) {
print("I am in row \(indexPath.row)")
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.myButton.myCell = cell
cell.myButton.myTable = tableView
// Other cell setup
return cell
}
CustomTableViewCell.swift:
class MyButton: UIButton {
weak var myTable: UITableView?
weak var myCell: UITableViewCell?
}
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var myButton: MyButton!
@IBAction func whereAmI(button: MyButton) {
if let myCell = button.myCell, indexPath = button.myTable?.indexPathForCell(myCell) {
print("I am in row \(indexPath.row)")
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.myButton.myCell = cell
cell.myButton.myTable = tableView
// Other cell setup
return cell
}
在TableViewController.swift中:
class MyButton: UIButton {
weak var myTable: UITableView?
weak var myCell: UITableViewCell?
}
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var myButton: MyButton!
@IBAction func whereAmI(button: MyButton) {
if let myCell = button.myCell, indexPath = button.myTable?.indexPathForCell(myCell) {
print("I am in row \(indexPath.row)")
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.myButton.myCell = cell
cell.myButton.myTable = tableView
// Other cell setup
return cell
}
要实现此功能,在Identity Inspector中将UIButton
和UITableViewCell
的类设置为MyButton
和CustomTableViewCell
非常重要。另外,将按钮连接到CustomTableViewCell.swift中的@IBOutlet
上。如果您使用的是自定义tableViewCell(可能是),则只需创建一个变量即可
class Cell: UITableViewCell {
var id = ""
@IBAction func buttonPressed(sender: AnyObject) {
print(id) // Can also call a function with 'id' as a parameter
}
}
以及:
该代码适用于Swift 5:
private func onTapButtonInsideCell(button: UIButton, event: UIEvent) {
guard let touches = event.touches(for: button), !touches.isEmpty else {
return
}
let touch = touches[touches.startIndex]
let point = touch.location(in: tableView)
guard let indexPath = tableView.indexPathForItem(at: point) else {
return
}
print("onTapButtonInsideCell() indexPath.row=\(indexPath.row)")
}
Github Gist:感谢您的快速回复,但是“table.indexPathForCell(cell)”仍然会向我返回nil。在我的例子中,“table”是通过IBOutlet连接的,按钮是部分(TableViewCell)的子视图。感谢您的快速回复,但是“tableView.indexPathForRowAtPoint(point)”和“tableView.indexPathForRowAtPoint(point)”仍然返回nil。在我的例子中,“table”是通过IBOutlet连接的,按钮是部分(TableViewCell)的子视图。感谢您的快速回复,我应用了您的解决方案。它对我有用。但我希望有一个合适的替代工作解决方案。不,如果可以添加或删除任何行,则使用基于indexPath的标记将不起作用。@rmaddy。说得好。我更新了我的答案以注意到这一点。由于其他答案对OP不起作用,我在一个新答案中采用了完全不同的方法。由于OP接受了我的原始答案,我不想编辑它,给人留下我的新答案被接受的印象。