如何向UITableViewCell添加手势?

我想为 UITableView 中的每个单元格添加一个点按手势,用于编辑其中的内容 . 添加手势的两种方式是在代码中或通过故事板 . 我试过了两次,但他们失败了 .

我可以通过故事板拖放为表格中的每个单元格添加手势吗?它似乎只为第一个单元添加手势 . 在代码中添加手势,我写了类似的东西,

addGestureRecognizer(UITapGestureRecognizer(target: self,action:#selector(MyTableViewCell.tapEdit(_:))))

要么

addGestureRecognizer(UITapGestureRecognizer(target: self, action:"tapEdit:"))

都工作 . 但是我想让 UITableViewController 处理这个手势,因为它对数据源做了一些事情 . 如何编写目标和操作?

编辑:

addGestureRecognizer(UITapGestureRecognizer(target: MasterTableViewController.self, action:#selector(MasterTableViewController.newTapEdit(_:)))

它引发一个错误说,无法识别的选择器发送到类0x106e674e0 ...

回答(4)

3 years ago

要向UITableViewCell添加手势,您可以按照以下步骤操作:

首先,将手势识别器添加到UITableView

tapGesture = UITapGestureRecognizer(target: self, action: #selector(tableViewController.tapEdit(_:)))
tableView.addGestureRecognizer(tapGesture!)
tapGesture!.delegate = self

然后,定义选择器 . 使用 recognizer.locationInView 找到您在tableView中点击的单元格 . 您可以通过 tapIndexPath 访问dataSource中的数据,这是用户点击的单元格的indexPath .

func tapEdit(recognizer: UITapGestureRecognizer)  {
    if recognizer.state == UIGestureRecognizerState.Ended {
        let tapLocation = recognizer.locationInView(self.tableView)
        if let tapIndexPath = self.tableView.indexPathForRowAtPoint(tapLocation) {
            if let tappedCell = self.tableView.cellForRowAtIndexPath(tapIndexPath) as? MyTableViewCell {
                //do what you want to cell here

            }
        }
    }
}

可以直接向TableView单元添加手势并访问viewController中的数据源,您需要设置一个委托:

In your custom cell:

import UIKit


class MyTableViewCell: UITableViewCell {

    var delegate: myTableDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewCell.tapEdit(_:)))
        addGestureRecognizer(tapGesture)
        //tapGesture.delegate = ViewController()

    }

    func tapEdit(sender: UITapGestureRecognizer) {
        delegate?.myTableDelegate()
    }

}

protocol myTableDelegate {
    func myTableDelegate() 
}

In your viewController:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate, myTableDelegate {

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
        // Do any additional setup after loading the view, typically from a nib.
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 35
    }

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

        cell?.delegate = self

        return cell!
    }

    func myTableDelegate() {
        print("tapped")
        //modify your datasource here
    }

}

但是,此方法可能会导致问题,请参阅UIGestureRecognizer and UITableViewCell issue . 在这种情况下,当滑动手势成功时,由于某种原因选择器被调用两次 . 我还没有找到任何直接证据,但在搜索谷歌之后,似乎第一种方法是标准方式 .

3 years ago

您无需添加手势识别器即可实现您的目标 .

  • 使用 UITableViewDelegate 方法 tableView:didSelectRowAtIndexPath: 来检测点击哪一行(这正是您的 tapGesture 将要执行的操作),然后执行所需的处理 .

  • 如果您在选择单元格时不喜欢灰色指示,请在返回单元格之前在 tableView:didEndDisplayingCell:forRowAtIndexPath: 中键入:
    cell?.selectionStyle = .None

3 years ago

在awakeFromNib方法中添加手势似乎更容易,并且工作正常 .

class TestCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()

        let panGesture = UIPanGestureRecognizer(target: self,
                                            action: #selector(gestureAction))
        addGestureRecognizer(panGesture)
    }

    @objc func gestureAction() {
        print("gesture action")
    }
}

3 years ago

在CellForRowAtIndexPath中,返回单元格之前 . 创建轻击手势并设置为单元格 .