web-dev-qa-db-fra.com

Comment ajouter un geste à UITableViewCell?

Je veux ajouter un geste de toucher à chaque cellule d'un UITableView qui modifie le contenu qu'il contient. Les deux façons d'ajouter un geste sont en code ou via le storyboard. J'ai essayé les deux et ils ont échoué.

Puis-je ajouter un geste à chaque cellule du tableau avec le glisser-déposer du storyboard? Il semble que cela n'ajoute qu'un geste à la première cellule. En ajoutant du geste dans le code, j'ai écrit quelque chose comme,

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

ou

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

les deux fonctionnent. Mais je voudrais laisser le UITableViewController gérer ce geste car il fait quelque chose avec la source de données. Comment écrire ma cible et mon action?

ÉDITER:

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

cela induit une erreur dit, sélecteur non reconnu envoyé à la classe 0x106e674e0 ...

10
Fate Riddle

Pour ajouter un geste à UITableViewCell, vous pouvez suivre les étapes ci-dessous:

Tout d'abord, ajoutez la reconnaissance des gestes à UITableView

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

Ensuite, définissez le sélecteur. Utilisation recognizer.locationInView pour localiser la cellule sur laquelle vous appuyez dans tableView. Et vous pouvez accéder aux données de votre source de données par tapIndexPath, qui est l'indexPath de la cellule que l'utilisateur a tapée.

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

            }
        }
    }
}

Il est possible d'ajouter un geste directement à la cellule TableView et d'accéder à la source de données dans viewController, vous devez configurer un délégué:

Dans votre cellule personnalisée:

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() 
}

Dans votre 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
    }

}

Cependant, cette méthode peut provoquer des problèmes, voir problème UIGestureRecognizer et UITableViewCell . Dans ce cas, lorsque le geste de balayage réussit, le sélecteur est appelé deux fois pour une raison quelconque. Je ne peux pas dire que la deuxième méthode est mauvaise car je n'ai pas encore trouvé de preuves directes, mais après avoir cherché sur Google, il semble que la première méthode soit la méthode standard.

38
billphilip22

Vous n'avez pas besoin d'ajouter de reconnaissance de gestes pour réaliser ce que vous faites.

  • Utilisez la méthode UITableViewDelegatetableView:didSelectRowAtIndexPath: pour détecter quelle ligne est tapée (c'est exactement ce que votre tapGesture va faire) puis effectuez le traitement souhaité.
  • Si vous n'aimez pas l'indication grise lorsque vous sélectionnez une cellule, saisissez-la dans votre tableView:didEndDisplayingCell:forRowAtIndexPath: juste avant de retourner la cellule:
    cell?.selectionStyle = .None
8
Rohan Sanap

Ajouter un geste dans la méthode awakeFromNib semble beaucoup plus facile et fonctionne très bien.

class TestCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()

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

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