2015-08-09 4 views
1

У меня есть список изображений внутри ячейки, в пределах UITableView. По причинам, по которым я не буду идти (слишком много), я не могу использовать didSelectRowAtIndexPath, чтобы узнать, какой из них был выбран из-за того, что я использую сторонний модуль, который добавляет собственные родительские жесты, и я не могу установить cancelsTouchesInView = false (что может технически решить мою проблему).Swift: получить произвольную информацию от UITapGestureRecognizer

В любом случае, есть способ добавить произвольную информацию в представление, так что, когда я получу ее как 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

Хотя я лично не рекомендую это использовать, но вы можете использовать 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.") 
    } 
} 
+0

Отлично! Это работало как шарм. Кроме того, любая причина не устанавливать жест, признанный в ячейке? Он отлично работал в моем примере (это означает, что я получил обратный вызов). – ded

+0

Я думаю, что он все равно будет работать, даже если вы установите распознаватель на ячейку тоже. Однако хорошей практикой всегда работать над 'contentView', а не с самой ячейкой в ​​соответствии с [Apple docs] (https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewCell_Class/index .html # // apple_ref/occ/instp/UITableViewCell/contentView) – ozgur

+0

Извините. Не знал, что я могу это сделать. Я довольно уверен, что пользователи с <= 200 не могут принять ответ в течение нескольких дней – ded

Смежные вопросы