Je voudrais gérer un UITableViewCell
long sur un UITableViewCell
pour imprimer un “menu d’access rapide”. Est-ce que quelqu’un l’a déjà fait?
En particulier, le geste reconnaît sur UITableView
?
Commencez par append le dispositif de reconnaissance des mouvements de la presse longue à la vue de la table:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; lpgr.minimumPressDuration = 2.0; //seconds lpgr.delegate = self; [self.myTableView addGestureRecognizer:lpgr]; [lpgr release];
Puis dans le gestionnaire de gestes:
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { CGPoint p = [gestureRecognizer locationInView:self.myTableView]; NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"long press on table view at row %ld", indexPath.row); } else { NSLog(@"gestureRecognizer.state = %ld", gestureRecognizer.state); } }
Vous devez faire attention à cela pour qu’il n’interfère pas avec le tapotement normal de l’utilisateur sur la cellule et notez également que handleLongPress
peut tirer plusieurs fois (ceci sera dû aux changements d’état de reconnaissance du geste).
J’ai utilisé la réponse d’Anna-Karenina, et cela fonctionne très bien avec un bug très sérieux.
Si vous utilisez des sections, appuyer longuement sur le titre de la section vous donnera un résultat erroné en appuyant sur la première ligne de cette section. J’ai ajouté une version fixe ci-dessous (y compris le filtrage des appels factices en fonction de l’état des gestes). Suggestion Anna-Karenina).
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { CGPoint p = [gestureRecognizer locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell.isHighlighted) { NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row); } } } }
Voici des instructions clarifiées combinant la réponse de Dawn Song et la réponse de Marmor.
Faites glisser un long appui sur la reconnaissance gestuelle et déposez-le dans votre cellule de tableau. Il sautera au bas de la liste à gauche.
Ensuite, connectez le dispositif de reconnaissance des gestes de la même manière que vous connecteriez un bouton.
Ajouter le code de Marmor dans le gestionnaire d’action
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateBegan) { CGPoint p = [sender locationInView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; if (cell.isHighlighted) { NSLog(@"long press on table view at section %d row %d", indexPath.section, indexPath.row); } } }
}
Semble être plus efficace pour append le dispositif de reconnaissance directement à la cellule, comme illustré ici:
Tapez et maintenez pour les cellules TableView, puis et maintenant
(défiler à l’exemple en bas)
Répondre à Swift:
Ajoutez le délégué UIGestureRecognizerDelegate
à votre UITableViewController.
Dans UITableViewController:
override func viewDidLoad() { super.viewDidLoad() let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:") longPressGesture.minimumPressDuration = 1.0 // 1 second press longPressGesture.delegate = self self.tableView.addGestureRecognizer(longPressGesture) }
Et la fonction:
func handleLongPress(longPressGesture:UILongPressGestureRecognizer) { let p = longPressGesture.locationInView(self.tableView) let indexPath = self.tableView.indexPathForRowAtPoint(p) if indexPath == nil { print("Long press on table view, not row.") } else if (longPressGesture.state == UIGestureRecognizerState.Began) { print("Long press on row, at \(indexPath!.row)") } }
Répondre à Swift 3.0 (Continuatuin de la réponse de Ricky dans Swift)
Ajoutez le
UIGestureRecognizerDelegate
à votre ViewController
override func viewDidLoad() { super.viewDidLoad() //Long Press let longPressGesture:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress)) longPressGesture.minimumPressDuration = 0.5 longPressGesture.delegate = self self.tableView.addGestureRecognizer(longPressGesture) }
Et la fonction:
func handleLongPress(longPressGesture:UILongPressGestureRecognizer) { let p = longPressGesture.location(in: self.tableView) let indexPath = self.tableView.indexPathForRow(at: p) if indexPath == nil { print("Long press on table view, not row.") } else if (longPressGesture.state == UIGestureRecognizerState.began) { print("Long press on row, at \(indexPath!.row)") } }
J’ai mis en place une petite catégorie sur UITableView basée sur l’excellente réponse d’Anna Karenina.
Comme ceci, vous aurez une méthode de délégation pratique, comme vous en avez l’habitude lorsque vous traitez des vues de table régulières. Vérifiez-le:
// UITableView+LongPress.h #import @protocol UITableViewDelegateLongPress; @interface UITableView (LongPress) @property(nonatomic,assign) id delegate; - (void)addLongPressRecognizer; @end @protocol UITableViewDelegateLongPress - (void)tableView:(UITableView *)tableView didRecognizeLongPressOnRowAtIndexPath:(NSIndexPath *)indexPath; @end // UITableView+LongPress.m #import "UITableView+LongPress.h" @implementation UITableView (LongPress) @dynamic delegate; - (void)addLongPressRecognizer { UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; lpgr.minimumPressDuration = 1.2; //seconds lpgr.delegate = self; [self addGestureRecognizer:lpgr]; } - (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer { CGPoint p = [gestureRecognizer locationInView:self]; NSIndexPath *indexPath = [self indexPathForRowAtPoint:p]; if (indexPath == nil) { NSLog(@"long press on table view but not on a row"); } else { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { // I am not sure why I need to cast here. But it seems to be alright. [(id)self.delegate tableView:self didRecognizeLongPressOnRowAtIndexPath:indexPath]; } } }
Si vous souhaitez l’utiliser dans un UITableViewController, vous devez probablement sous-classer et vous conformer au nouveau protocole.
Cela fonctionne très bien pour moi, j’espère que cela aidera les autres!
Ajoutez simplement UILongPressGestureRecognizer à la cellule prototype donnée dans le storyboard, puis déplacez le geste vers le fichier .m de viewController pour créer une méthode d’action. Je l’ai fait comme je l’ai dit.
Swift 3 répond en utilisant la syntaxe moderne, en incorporant d’autres réponses et en éliminant les codes inutiles.
override func viewDidLoad() { super.viewDidLoad() let recognizer = UILongPressGestureRecognizer(target: self, action: #selector(tablePressed)) tableView.addGestureRecognizer(recognizer) } @IBAction func tablePressed(_ recognizer: UILongPressGestureRecognizer) { let point = recognizer.location(in: tableView) guard recognizer.state == .began, let indexPath = tableView.indexPathForRow(at: point), let cell = tableView.cellForRow(at: indexPath), cell.isHighlighted else { return } // TODO }
Utilisez la propriété d’horodatage UITouch dans touchesBegan pour lancer une timer ou l’arrêter lorsque touchEnded est déclenché