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 ...
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.
Vous n'avez pas besoin d'ajouter de reconnaissance de gestes pour réaliser ce que vous faites.
UITableViewDelegate
tableView:didSelectRowAtIndexPath:
pour détecter quelle ligne est tapée (c'est exactement ce que votre tapGesture
va faire) puis effectuez le traitement souhaité.tableView:didEndDisplayingCell:forRowAtIndexPath:
juste avant de retourner la cellule:cell?.selectionStyle = .None
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")
}
}