2009-02-10 12 views
20

Ho una vista UIImage che risponde agli eventi di tocco. Voglio annullare la sequenza di tocco, ovvero ulteriori chiamate allo touchesMoved:, se il tocco supera determinati limiti. Come lo posso fare?Come cancellare una sequenza di eventi UITouch?

So che in touchesMoved: riesco a controllare le coordinate dell'oggetto touch e ignorarlo, ma quello che non so è come annullare del tutto la sequenza. Non vedo alcun metodo documentato nello Apple Developer UIResponder Reference che posso chiamare per cancellare una sequenza di tocco.

risposta

6

Questa soluzione può essere un po 'kludgy, ma si potrebbe implementare e chiamare manualmente

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 

sto basando questa soluzione liberamente su qualche ritocco che ho fatto per il campione app moveme sul sito di Apple iPhone sample code in cui ho modificato il touchesMoved metodo per apparire come questo:

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    if ([touch view] == placardView) 
     CGPoint location = [touch locationInView:self]; 
     placardView.center = location; 
     // I added the following line: 
     [self touchesCancelled:touches withEvent:event]; 
     return; 
} 
+1

Grazie, ci provo quando torno al mio mac. Ma questo annullerà i successivi tocchi? Mi sembra che dopo una chiamata manuale a touchesCancelled, i touchesMoved vengano comunque chiamati dal sistema. –

+0

Entro i confini del codice di esempio MoveMe annullerà il tocco, ma credo che tu abbia ragione, i tocchi di Move sarebbero ancora chiamati. Più ci penso, meno ritengo che touchCancelled sia la chiamata giusta. –

+0

Questo non funziona e gli eventi "move" continuano ad arrivare sempre dopo. – Andy

2

ho affrontato lo stesso problema da poco e ha trovato un modo standard per risolverlo. È possibile utilizzare [[Applicazione condivisa UIA] beginIgnoringInteractionEvents] per interrompere la consegna di tocchi Eventi spostati sull'intera app. Assicurati di abilitarli usando [[UIApplication sharedApplication] endIgnoringInteractionEvents] quando devi ricevere nuovamente i tocchi.

3

È necessario chiamare [super touchesMoved:withEvent:] per permettere la vista eccellente ripulire dalla manifestazione ma ancora più importante, è necessario non chiamata [super touchesCancelled:withEvent:].

Ecco quello che ho usato su una cella per tenerlo da ottenere selezionato quando ho rilevato un colpo:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if (!showingEdit) { 
     if (IS_FAR_ENOUGH_TO_BE_A_SWIPE) { 
      RESPOND_TO_SWIPE 
      showingEdit = YES; 
      [super touchesCancelled:touches withEvent:event]; 
     } else { 
      [super touchesMoved:touches withEvent:event]; 
     } 
    } 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if (!showingEdit) { 
     [super touchesEnded:touches withEvent:event]; 
    } 
} 
+1

Questo non ha funzionato per me. – ma11hew28

2

non credo che sia possibile, perché io non lo vedo documentato e nessuna di queste soluzioni lavoro.

-2

È possibile verificare che le posizioni dei punti di contatto siano in CGRect (ad esempio, i punti sono in Rectangle della visualizzazione di immagini) oppure no. Se non sono in quel Rect, il tocco sarà annullato.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
UITouch *touch = [touches anyObject]; 
CGPoint touchLocation = [touch locationInView:self.view]; 

    if (CGRectContainsPoint(myImageView, touchLocation)) 
    { 
     lastPoint = [touch locationInView: myImageView]; 
    } 

    NSLog(@"Last :%.2f - %.2f",lastPoint.x, lastPoint.y); 
    } 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    CGPoint currentPoint; 
    UITouch *touch = [touches anyObject]; 
    CGPoint touchLocation = [touch locationInView:self.view]; 

    if (CGRectContainsPoint(myImageView.frame, touchLocation)) 
    { 
     currentPoint = [touch locationInView: myImageView]; 
    } 
} 
+1

Questo codice non cancella ulteriori chiamate a 'touchesMoved:'. Li ignora semplicemente. – ma11hew28

0

Su iOS5 sembra che ci sia un metodo privato in UITouch

-(void)setSentTouchesEnded:(BOOL)ended; 

A seconda l'implementazione di Apple potrebbe interrompere l'invio di eventi

Un altro modo di farlo sarebbe utilizzando oggetti associativa

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if ([(NSNumber *)objc_getAssociatedObject(touch, &outKey) boolValue]) 
     return; 
    if (sometouchisoutsideofview) { 
     objc_setAssociatedObject(touch, &outKey, [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN); 
    } 
} 
3

Provare impostazioni temporanee dell'utente di UIImageView Interazione Proprietà abilitata a NO

0

Stavo solo cercando di risolvere qualcosa di simile, e ho scoperto che nessuna delle soluzioni elencate la sua ha funzionato per me. Il meglio che potevo gestire era di ignorare temporaneamente i tocchi, ma poi riprendevano quando il tocco rientrava nella vista.

Finalmente risolto.

  1. Impostare un flag booleano chiamato "disabile"
  2. In touchedMoved, verificare innanzitutto che il tocco è dentro la vista desiderata. Se non lo è, imposta il flag disabilitato su SÌ.
  3. Ancora in contatto rimosso, controlla la bandiera prima di eseguire l'azione. Quindi, a questo punto, non accadrà nulla se sono fuori dalla vista.
  4. In touchesEnded, impostare il flag disabilitato su NO. Quindi la sequenza tattile viene effettivamente fermata finché l'utente non alza il dito.

Immagino che questo funzionerà per te a meno che tu non abbia una ragione specifica per aver letteralmente bisogno della sequenza di tocchi cancellata.

+0

Puoi persino eseguire il tracciamento in stile UIControl utilizzando un singolo flag. Il che è più naturale che se l'intera sequenza di eventi fosse cancellata in una sola volta. – Andy

1

Soluzione "forza bruta" a seconda se si adatta alle proprie esigenze: rimuovere e reinizializzare la sottoview che riceve i tocchi o risponde a loro (ovviamente prendersi cura di frame e contenuto).

-1

È possibile creare una categoria su UITouch. Si può dichiarare

@property (nonatomic,strong,readwrite) UIView *view; 

E quando si cambia touch.view a zero, per esempio, è possibile simulare fine del dispacciamento eventi touch

1

Questo codice vi aiuterà. A disattivare evento di tocco in touchesMoved: metodo e sto consentendo tocco evento nel touchesCancelled: metodo

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    ....... 
    ....... 
    Your code 
    ....... 
    ....... 

    //Condition when you want to disable touch event 

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; 

    ....... 
    ....... 
    Your code 
    ....... 
    ....... 
} 


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [[UIApplication sharedApplication] endIgnoringInteractionEvents]; 
} 
+0

Questo non ha funzionato per me. – avance

1

ho raggiungere questo rimuovendo la vista dalla sua superview e aggiungendo subito indietro.

[view retain]; 
UIView *sv = view.superview; 
[view removeFromSuperview]; 
[sv addSubview:view]; 
[view release]; 

Questo interrompe la catena di risposta alla vista in modo che i restanti tocchi non vengano ricevuti sulla vista. Il prossimo tocco verrà comunque ricevuto normalmente.