Question

Je voudrais gérer une pression longue sur une UITableViewCell pour imprimer un « menu d'accès rapide ». Quelqu'un at-il déjà fait cela?

En particulier, le geste reconnaît le UITableView?

Était-ce utile?

La solution

Tout d'abord ajouter le temps presse geste à la reconnaissance vue de tableau:

UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
  initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self;
[self.myTableView addGestureRecognizer:lpgr];
[lpgr release];

Ensuite, dans le gestionnaire de geste:

-(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 être prudent avec cela pour que cela ne gêne et notez également les écoutes normales de la cellule de l'utilisateur qui handleLongPress peut tirer plusieurs fois (ce sera en raison des changements d'état de reconnaissance de geste).

Autres conseils

Je l'ai utilisé la réponse d'Anna-Karénine, et il fonctionne très bien avec presque un bug très sérieux.

Si vous utilisez des sections, appuyant longuement sur le titre de la section vous donnera un résultat erroné d'appuyer sur la première ligne sur cette section, j'ai ajouté une version fixe ci-dessous (y compris le filtrage des appels fictifs en fonction du geste état, par suggestion Anna-Karénine).

- (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 clarifiées instructions combinant la réponse de chanson Dawn et la réponse de Marmor.

Faites glisser une longue Gesture Appuyez sur Recognizer et déposez-le dans votre cellule du tableau. Il saute au bas de la liste à gauche.

 entrer image description ici

Connectez ensuite le geste de reconnaissance de la même façon que vous connectez un bouton. entrer la description d'image ici

Ajoutez 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);
        }
    }
}

}

Réponse à Swift 5 (Suite de la réponse à Swift Ricky)

  

Ajoutez le UIGestureRecognizerDelegate à votre ViewController

 override func viewDidLoad() {
    super.viewDidLoad()

    //Long Press
    let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
    longPressGesture.minimumPressDuration = 0.5
    longPressGesture.delegate = self
    self.tableView.addGestureRecognizer(longPressGesture)
 }
  

Et la fonction:

@objc 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 == UIGestureRecognizer.State.began {
        print("Long press on row, at \(indexPath!.row)")
    }
}

semble être plus efficace d'ajouter directement à la reconnaissance de la cellule comme indiqué ici:

Tap & Hold pour des TableView cellules, et ensuite maintenant

(défilement pour l'exemple en bas)

Réponse à Swift:

Ajouter 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)")
    }

}

Je mis en place une petite catégorie sur UITableView basée sur une excellente réponse d'Anna Karénine.

Comme cela, vous aurez une méthode déléguée pratique comme vous avez l'habitude de traiter avec des vues lors de la table régulière. Check it out:

//  UITableView+LongPress.h

#import <UIKit/UIKit.h>

@protocol UITableViewDelegateLongPress;

@interface UITableView (LongPress) <UIGestureRecognizerDelegate>
@property(nonatomic,assign)   id <UITableViewDelegateLongPress>   delegate;
- (void)addLongPressRecognizer;
@end


@protocol UITableViewDelegateLongPress <UITableViewDelegate>
- (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<UITableViewDelegateLongPress>)self.delegate tableView:self didRecognizeLongPressOnRowAtIndexPath:indexPath];
        }
    }
}

Si vous voulez utiliser dans un UITableViewController, vous avez probablement besoin de sous-classe et conforme au nouveau protocole.

Il fonctionne très bien pour moi, espérons qu'il aide les autres!

Swift 3 réponse, en utilisant la syntaxe moderne, incorporant d'autres réponses, et en éliminant le code inutile.

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
}

Il suffit d'ajouter UILongPressGestureRecognizer à la cellule prototype donné en story-board, puis tirez le geste fichier .m du viewController pour créer une méthode d'action. Je l'ai fait comme je le disais.

Utilisez la propriété d'horodatage UITouch dans touchesBegan pour lancer une minuterie ou arrêter quand touchesEnded a été congédiée

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top