按下按钮时,在UITableViewCell内找到按钮的indexPath?

时间:2014-11-24 13:25:50

标签: uitableview swift uibutton

以下代码正确返回单元格:

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)!

6 个答案:

答案 0 :(得分:10)

以下是按钮TouchUpInside事件的候选操作方法。

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

答案 1 :(得分:1)

您似乎无法从代码中找到tableView来处理按钮的@IBAction

您可以创建一个UIButton子类,跟踪按钮所在的cell和包含该单元格的UITableView。然后,这是一个简单的调用问题按钮tableView:indexPathForCell中的@IBAction

<强> MyButton.swift:

class MyButton: UIButton {
    weak var myTable: UITableView?
    weak var myCell:  UITableViewCell?
}

<强> CustomTableViewCell.swift:

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)")
        }
    }
}

TableViewController.swift中:

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
}

要使其发挥作用,请务必在身份检查器中设置UIButtonUITableViewCellMyButtonCustomTableViewCell的类。另外,将按钮连接到@IBOutlet中的CustomTableViewCell.swift

答案 2 :(得分:0)

我不知道是否有一种简单的方法可以做到这一点。 (编辑:实际上有。看看@ mustafa的第二个解决方案。)解决方法是将按钮的标记设置为indexPath.row中的cellForRowAtIndexPath,然后您只需访问该按钮即可标记以找出它属于哪一行。

警告:此变通方法很脆弱。如果您允许在表中添加或删除行而不调用tableView.reloadData(),则无法正常工作。看看@ mustafa的解决方案,它更加强大。

答案 3 :(得分:0)

func findSuperView(sender: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)")
}

答案 4 :(得分:0)

如果你正在使用自定义tableViewCell(你可能是),你可以创建一个变量。

class Cell: UITableViewCell {

    var id = ""

    @IBAction func buttonPressed(sender: AnyObject) {
        print(id) // Can also call a function with 'id' as a parameter
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: Cell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! Cell

    cell.id = indexPath.row // Or however you wan't to give it an Id

    return cell
}

答案 5 :(得分:0)

此代码可用于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要点:https://gist.github.com/rsaenzi/13dc00b5cb5a09efa84eaff3ff4682af