从 UITapGestureRecognizer 获取 UITableViewCell

Posted

技术标签:

【中文标题】从 UITapGestureRecognizer 获取 UITableViewCell【英文标题】:Getting UITableViewCell from UITapGestureRecognizer 【发布时间】:2015-03-31 04:33:24 【问题描述】:

我有一个包含多个部分的 UITableView,在我的 cellForRowAtIndexPath 方法中,我向单元格的 imageView 添加了一个 UITapGestureRecognizer(每个单元格都有一个小图像)。我已成功访问该图像(以更改它),方法是:

var imageView : UIImageView! = sender.view! as UIImageView

然而,我现在需要做的是访问单元格的数据,我相信这意味着我需要能够访问单元格才能获取节和行号。谁能建议如何做到这一点?这个想法是,如果任务完成,我会将图像更改为未选中的复选框,但随后在我的数据中我需要将该任务实际标记为已完成。

【问题讨论】:

【参考方案1】:

在处理点击手势识别器的函数中,使用tableViewindexPathForRowAtPoint 函数获取触摸事件的可选索引路径,如下所示:

func handleTap(sender: UITapGestureRecognizer) 
    let touch = sender.locationInView(tableView)
    if let indexPath = tableView.indexPathForRowAtPoint(touch) 
        // Access the image or the cell at this index path
    

从这里,您可以调用cellForRowAtIndexPath 来获取单元格或其任何内容,因为您现在拥有被点击单元格的索引路径。

【讨论】:

嗨,这几乎成功了!但是,该位置必须不正确,因为它正在对错误的单元格执行操作。对此有什么想法吗?【参考方案2】:

您可以获取点击图像的位置以找到 indexPath 并从那里找到具有该图像的单元格:

var position: CGPoint =  sender.locationInView(self.tableView)
var indexPath: NSIndexPath = self.tableView.indexPathForRowAtPoint(position)!    
var cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)

【讨论】:

嗨,这几乎成功了!但是,位置必须不正确,因为它正在对错误的单元格执行操作。对此有什么想法吗? 应该是:var cell = self.tableView.cellForRowAtIndexPath(indexPath)【参考方案3】:

您错过了可以在此处使用委托设计模式。

创建一个协议,告诉代表您的复选框 (imageView) 中的状态变化:

enum CheckboxState: Int 
    case .Checked = 1
    case .Unchecked = 0


protocol MyTableViewCellDelegate 
    func tableViewCell(tableViewCell: MyTableViewCell, didChangeCheckboxToState state: CheckboxState)

假设你有一个UITableViewCell 子类:

class MyTableViewCell: UITableViewCell 

    var delegate: MyTableViewCellDelegate?

    func viewDidLoad() 

        // Other setup here...

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "didTapImage:")
        imageView.addGestureRecognizer(tapGestureRecognizer)
        imageView.userInteractionEnabled = true
    

    func didTapImage(sender: AnyObject) 

        // Set checked/unchecked state here
        var newState: CheckboxState = .Checked // depends on whether the image shows checked or unchecked

        // You pass in self as the tableViewCell so we can access it in the delegate method
        delegate?.tableViewCell(self, didChangeCheckboxToState: newState)
    


在你的UITableViewController 子类中:

class MyTableViewController: UITableViewController, MyTableViewCellDelegate 

    // Other methods here (viewDidLoad, viewDidAppear, etc)...

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) 
        var cell = tableView.dequeueReusableCellWithIdentifier("YourIdentifier", forIndexPath: indexPath) as MyTableViewCell

        // Other cell setup here...

        // Assign this view controller as our MyTableViewCellDelegate
        cell.delegate = self

        return cell
    

    override func tableViewCell(tableViewCell: MyTableViewCell, didChangeCheckboxToState state: CheckboxState) 

        // You can now access your table view cell here as tableViewCell

    


希望这会有所帮助!

【讨论】:

UITableViewCell 没有 viewDidLoad 方法 使用 awakeFromNib 代替 viewDidLoad【参考方案4】:

获取 tableView 在特定单元格上的单元格位置。调用一个函数来保存单元格对象的手势,如 UIImage 等。

let location = gesture.location(in: tableView)
   let indexPath = tableView.indexPathForRow(at: location)
   Print(indexPath.row)
   Print(indexPath.section)

【讨论】:

以上是关于从 UITapGestureRecognizer 获取 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

iOS 为啥不能从 UITapGestureRecognizer 调用方法 collectionView:didSelectItemAtIndexPath:?

无法从情节提要中的 UITapGestureRecognizer 拖动 IBAction

使用 UITapGestureRecognizer 从点击的单元格中获取标签文本

如何为 UITapGestureRecognizer 从不同的 UIView 对象设置选择器

使用 UITapGestureRecognizer 无法识别的选择器

UITapGestureRecognizer 的动作在进行中时无法调用?