Domanda

Mi piacerebbe gestire una pressione prolungata su un UITableViewCell per stampare un "menu di accesso rapido". Qualcuno ha già fatto questo?

In particolare il gesto di riconoscere il UITableView?

È stato utile?

Soluzione

In primo luogo aggiungere la pressione prolungata gesto riconoscitore alla vista tabella:

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

Poi nel gestore gesto:

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

Bisogna stare attenti con questo in modo che non interferisca con il normale spillatura dell'utente del cellulare e anche notare che handleLongPress possono sparare più volte (questo sarà dovuto ai cambiamenti di stato gesto riconoscitore).

Altri suggerimenti

Ho usato la risposta di Anna Karenina-, e funziona quasi grande con un gravissimo errore.

Se stai usando le sezioni, a lungo premendo il titolo della sezione vi darà un risultato sbagliato di premere prima fila su quella sezione, ho aggiunto una versione fissa di seguito (compreso il filtraggio delle chiamate fittizie sulla base del gesto stato, per Anna Karenina-suggerimento).

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

di istruzioni Qui sono chiarito che unisce la risposta di Dawn Song e la risposta di Marmor.

Trascinare una pressione prolungata Gesture Recognizer e rilasciarlo nella vostra cella tabella. Si passa al fondo della lista di sinistra.

 entrare descrizione dell'immagine qui

Poi collegare il gesto riconoscitore allo stesso modo in cui si collegare un pulsante. entrare image description qui

Aggiungere il codice Marmor nel gestore di azione

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

}

Risposta a Swift 5 (Continuazione della risposta di Ricky a Swift)

  

Aggiungere il UIGestureRecognizerDelegate al 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)
 }
  

E la funzione:

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

sembra essere più efficiente per aggiungere il sistema di riconoscimento direttamente alla cella come illustrato di seguito:

Toccare e tenere premuto per TableView Cells, Allora e ora

(di scorrimento per l'esempio in basso)

Risposta a Swift:

Aggiungi delegato UIGestureRecognizerDelegate al UITableViewController.

In 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)

}

E la funzione:

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

}

Ho messo insieme un po 'di categoria sul UITableView in base alla risposta eccellente di Anna Karenina.

Ti piace questa avrete un metodo delegato comoda come si è abituati a quando si tratta di vista regolari tavolo. 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];
        }
    }
}

Se si desidera utilizzare questo in un UITableViewController, probabilmente bisogno di sottoclasse e conforme al nuovo protocollo.

E le grandi opere per me, spero che aiuta gli altri!

Swift 3 risposta, utilizzando la sintassi moderna, incorporando altre risposte, ed eliminando il codice non necessario.

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
}

Basta aggiungere UILongPressGestureRecognizer alla data cella prototipo nel storyboard, quindi tirare il gesto di file di .m del viewController di creare un metodo di azione. L'ho fatto come ho detto.

Utilizzare la proprietà timestamp UITouch in touchesBegan per lanciare un timer o fermarlo quando touchesEnded stato licenziato

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top