2013-02-01 3 views
7

Sto scrivendo un programma Objective-C per iPhone.UILongPressGestureRecognizer non risponderà al touch & HOLD

Sto cercando di implementare un UILongPressGestureRecognizer e non riesco a farlo funzionare come voglio io.

Quello che voglio fare è semplice:

rispondere a un tocco di essere tenuto verso il basso sullo schermo.

Il UILongPressGestureRecognizer funziona perfettamente ogni volta che il tocco si muove e quando inizia il tocco, ma se tengo premuto il tocco nello stesso punto, non accade nulla.

Perché?

Come posso gestire un tocco che inizia, non si muove e rimane nello stesso identico luogo?

Ecco il mio codice corrente.


// Configure the press and hold gesture recognizer 
touchAndHoldRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(touchAndHold:)]; 
touchAndHoldRecognizer.minimumPressDuration = 0.1; 
touchAndHoldRecognizer.allowableMovement = 600; 
[self.view addGestureRecognizer:touchAndHoldRecognizer]; 
+0

// Configura la pressione e tieni premuto il riconoscimento del gesto touchAndHoldRecognizer = [[Assegnazione UILongPressGestureRecognizer] initWithTarget: self action: @selector (touchAndHold :)]; touchAndHoldRecognizer.minimumPressDuration = 0,1; touchAndHoldRecognizer.allowableMovement = 600; [self.view addGestureRecognizer: touchAndHoldRecognizer]; –

+0

Il mio punto esattamente. Non si ottengono eventi ripetuti se non si sposta. Questo è quello che sto cercando di risolvere. Conoscete un metodo con cui I -can- ottiene ripetuti eventi se non mi muovo? –

+2

Questo dovrebbe essere riaperto perché se si guarda attentamente a cosa sta ponendo questa domanda, non si sta chiedendo "come faccio un gesto di lunga pressione", ma piuttosto "ora ricevo le notifiche nel mezzo di un lungo gesto di pressione, anche anche se non mi sto muovendo. " Questo non è un duplicato di quell'altra domanda. – Rob

risposta

12

Il comportamento descritto, in cui il vostro sistema di riconoscimento gesto non riceve ulteriori chiamate al gestore quando non sei in movimento è il comportamento standard. La proprietà state per questi movimenti durante lo spostamento è di tipo UIGestureRecognizerStateChanged, quindi è logico che se le cose non sono cambiate, il gestore non verrà chiamato.

Si potrebbe

  • Su chiamata al sistema di riconoscimento gesto con state di UIGestureRecognizerStateBegan avviare un timer ripetuto;
  • Su chiamata al proprio riconoscitore di gesti con state di UIGestureRecognizerStateCancelled, UIGestureRecognizerStateFailed o UIGestureRecognizerStateEnded quindi invalidate e rilasciare il timer;
  • Assicurarsi che il metodo gesto riconoscitore sta salvando qualsiasi valore che stai cercando in qualche proprietà di classe (ad esempio, il valore di locationInView o qualsiasi altra cosa)

Così, forse qualcosa di simile:

@interface ViewController() 

@property (nonatomic) CGPoint location; 
@property (nonatomic, strong) NSTimer *timer; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; 
    gesture.minimumPressDuration = 0.1; 
    gesture.allowableMovement = 600; 
    [self.view addGestureRecognizer:gesture]; 
} 

- (void)handleTimer:(NSTimer *)timer 
{ 
    [self someMethod:self.location]; 
} 

- (void)handleGesture:(UIGestureRecognizer *)gesture 
{ 
    self.location = [gesture locationInView:self.view]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; 
    } 
    else if (gesture.state == UIGestureRecognizerStateCancelled || 
      gesture.state == UIGestureRecognizerStateFailed || 
      gesture.state == UIGestureRecognizerStateEnded) 
    { 
     [self.timer invalidate]; 
     self.timer = nil; 
    } 

    [self someMethod:self.location]; 
} 

- (void)someMethod:(CGPoint)location 
{ 
    // move whatever you wanted to do in the gesture handler here. 

    NSLog(@"%s", __FUNCTION__); 
} 

@end 
+0

... Penso che sto iniziando a capirlo. Il mio problema era che non stavo capendo la metodologia di Apple con il modo in cui trattavano i tocchi. Penso che il motivo per cui trascorro 4 ore oggi perlustrando internet per trovare risposte e diventando sempre più frustrato è che mi mancava il punto.Mi hai aiutato a vedere questo Rob. Non c'è nessun metodo in Cocoa come "handleTouchesRemainedStationary" perché se un tocco non è terminato e non si è spostato ... Quindi __obviously__ è rimasto lo stesso. Puoi continuare a ripetere il ciclo di esecuzione. Grazie, Rob! –

+0

@ J-Rock Cool. L'implementazione potrebbe variare (ad esempio, è possibile reimpostare il timer su un gesto, in modo da non ricevere chiamate con il timer se ci si sposta), ma si ottiene l'idea. Cordiali saluti, ho semplificato un po 'il mio codice. – Rob

+0

@ J-Rock E un'ultima osservazione, a cui ho accennato prima. Se vuoi un gesto continuo che inizia molto velocemente dopo aver toccato lo schermo e continua mentre ti muovi, potresti voler usare un 'UIPanGestureRecognizer'. Se questo funziona per te, ha più senso. La maggior parte dei programmatori sarebbe fuorviata dall'uso di un riconoscitore di gesti a pressione lunga che consente il movimento di 600 punti. Se per qualche motivo è necessario utilizzare la stampa lunga (ad esempio, è importante avere un'attesa di 0.1 all'inizio), altrimenti utilizzarla, in alternativa, "UIPanGestureRecognizer". – Rob