Swift:从UITapGestureRecognizer获取任意信息

时间:2015-08-09 00:09:58

标签: ios swift

我在UITableView内的单元格中有一个图像列表。由于我不会去(太多)的原因,我不能使用didSelectRowAtIndexPath知道哪一个被选中,因为我正在使用第三方模块添加其自己的父母手势,我无法设置cancelsTouchesInView = false(这在技术上可以解决我的问题)。

在任何一种情况下,是否有办法向视图添加任意信息,因此当我以sender的形式收到它时,我可以反省它。

例如:如果这是HTML& JavaScript,你可以这样做。

$(myImage).data('foo', 'bar')
$(anotherImage.data('foo', 'thunk')

$('img').on('click', function () {
  console.log($(this).data('foo')) // could be "foo" or "thunk"
})

在Swift中

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  var cell = MyCustomTableViewCell()
  cell.userInteractionEnabled = true
  let tapped = UITapGestureRecognizer(target: self, action: Selector("myCallback:"))
  cell.addGestureRecognizer(tapped)


  // my imaginary world...
  cell.foo = self.extraData[indexPath.row]

  return cell
}

func myCallback(sender: AnyObject?) {
  println(sender.foo)
}

显然,上述方法并不奏效,但有没有办法实现我想要做的事情?

1 个答案:

答案 0 :(得分:1)

虽然我个人不建议使用那么多,但如果你想在运行时将额外的数据附加到对象,你可以使用objc_setAssociatedObject

以下是有关如何在Swift中执行此操作的一个很好的资源:

http://nshipster.com/swift-objc-runtime/

或者,UIView类有一个名为tag的属性,您可以在其中指定indexPath.row来获取稍后点击的单元格:

cell.tag = indexPath.row
顺便说一下,你最好不要在细胞上工作。相反,当您想要添加手势或其他子视图等时,始终对其contentView属性进行操作。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    ...
    cell.contentView.userInteractionEnabled = true

    // Always remove previously added tap gestures because cells are reused
    // as you scroll up and down so you'll end up having multiple 
    // recognizers on the same cell otherwise.
    for recognizer in cell.contentView.gestureRecognizers {
        cell.contentView.removeGestureRecognizer(recognizer)
    }

    cell.contentView.addGestureRecognizer(
        UITapGestureRecognizer(target: self, action: "myCallback:"))

    cell.contentView.tag = indexPath.row

    ...
    return cell
}

让单元格回调函数非常简单:

(假设您只有一个部分,以便indexPath.section = 0)

func myCallback(sender: UIGestureRecognizer) {
    let indexPath = NSIndexPath(forRow: sender.view.tag , inSection: 0)         

    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        print("Cell \(cell) has been tapped.")
    }
}