如何使tableViewCell处理点击和长按两个手势?

18

我把这个放在了cellForRowAtIndexPath里面。

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(CalorieCountViewController.handleLongPress))
cell.addGestureRecognizer(longPress)
longPress.cancelsTouchesInView = true
let tapPress = UITapGestureRecognizer(target: self, action: #selector(CalorieCountViewController.handleTapPress))
cell.addGestureRecognizer(tapPress)
tapPress.cancelsTouchesInView = true
将下面的代码放在外面,并完全删除didSelectRowAtIndexPath函数,改用indexPathForSelectedRow来获取用户刚刚选择的行。

将下面的代码放在外面,并完全删除didSelectRowAtIndexPath函数,改用indexPathForSelectedRow来获取用户刚刚选择的行。

func handleLongPress(sender: UILongPressGestureRecognizer){
    let index = tableView.indexPathForSelectedRow!
    doSomething(index)
}

func handleTapPress(sender: UITapGestureRecognizer){
    let index = tableView.indexPathForSelectedRow!
    doSomethingElse(index)
}

结果发现indexPathForSelectedRow返回nil,但我确实选择了一行,在我的代码中也没有任何"deselectRowAtIndexPath"。


只需在UITableViewCell上添加长按手势,对于轻击,您可以使用UITableView的“didSelectRowAtIndexPath”委托方法。 - Sandeep Kumar
3个回答

43

不要将UILongPressGestureRecognizer添加到Cell中。在viewDidLoad中将其添加到UITableView中。

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(sender:)))
tableView.addGestureRecognizer(longPress)

通过以下方式获取被触碰的单元格索引:

@objc private func handleLongPress(sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        let touchPoint = sender.location(in: tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            // your code here, get the row for the indexPath or do whatever you want
        }
    }
}

使用didSelectRowAtIndexPath而不是UITapGestureRecognizer是更好的方式。


2
长按手势识别器是什么?你应该更改方法中参数的名称。 - Shivam Pokhriyal

6

更新Swift4:

在您的视图控制器类中(本示例中类名为YourViewController)的viewDidLoad方法中添加以下行:

override func viewDidLoad() {
    super.viewDidLoad()

    let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPress(longPressGestureRecognizer:)))
    self.view.addGestureRecognizer(longPressRecognizer)
}

现在将这个func添加到您的视图控制器类中。
@objc func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {

    if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
        let touchPoint = longPressGestureRecognizer.location(in: self.view)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {
            // add your code here
            // you can use 'indexPath' to find out which row is selected
        }
    }
}

1
这实际上会显示错误的indexPath。您需要在viewDidLoad中将gestureRecognizer添加到tableView而不是视图中。将self.view.addGestureRecognizer(longPressRecognizer)替换为tableView.addGestureRecognizer(longPressRecognizer)。此外,将let touchPoint = longPressGestureRecognizer.location(in: self.view)更改为let touchPoint = longPressGestureRecognizer.location(in: tableView) - Phontaine Judd

5

以下是基于Bala在Swift 4或5上的回答。

override func viewDidLoad() {
        super.viewDidLoad()
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longpress))
        tableView.addGestureRecognizer(longPress)
    }

这里是方法。
@objc func longPress(sender: UILongPressGestureRecognizer) {

            if sender.state == UIGestureRecognizer.State.began {
                let touchPoint = sender.location(in: tableView)
                if let indexPath = tableView.indexPathForRow(at: touchPoint) {
                    // your code here, get the row for the indexPath or do whatever you want
                    print("Long press Pressed:)")
                }
            }


        }

建议将 action 参数更改为 #selector(longPress)。目前它是全部小写,因此是一个未解决的符号。 - John Harrington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接