2012-03-13 10 views
6

Sto utilizzando la classe UILongPressGestureRecognizer per gestire se un elemento è selezionato.UILongPressGestureRecognizer arresta la maniglia senza interrompere il contatto

La logica è la seguente: L'utente preme per 1 secondo un elemento (sottoclasse UIView). Una volta rilevato il gesto, l'oggetto viene evidenziato e spostato.

L'utente deve spostare questo elemento sullo schermo senza smettere di toccarlo.

Il problema che sto affrontando è il tocco di ombre riconosciuto dal tocco. Began/Move/Ended necessario per la classe dell'oggetto per organizzare il movimento.

Ho provato a rimuovere il gesto riconosciuto una volta rilevato e l'elemento selezionato. Tuttavia, l'invio di messaggi alla maniglia del gesto invece della chiamata tocca i metodi.

Qualcuno sa come smettere di "ascoltare" il riconoscitore di gesti senza lasciare il dito sullo schermo?

Grazie.

Ecco il codice:

-(void)addGestures 
{ 
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] 
               initWithTarget:self 
               action:@selector(handleLongPress:)]; 
    longPress.minimumPressDuration = iItemLongPressTime; 
    [self addGestureRecognizer:longPress]; 
    [longPress release]; 
} 
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) { 

     NSLog(@"Long press Ended"); 
    } 
    else { 
     if (self.isSelected) return; 

     if ([delegate respondsToSelector:@selector(singleTouch:)]) 
      [delegate singleTouch:self]; 

     [self removeGestureRecognizer:[self.gestureRecognizers objectAtIndex:0]]; 

     NSLog(@"Long press detected."); 
    } 
} 

Come si può vedere nel ramo altrimenti il ​​delegato chiama abilita tutte le procedure per contrassegnare questa voce come selezionato, e subito dopo togliere i sistemi di riconoscimento.

Cosa mi manca?

--EDIT--

Fatto! Funziona:

#pragma mark Gesture Functions 
-(void)addGestures 
{ 
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] 
               initWithTarget:self 
               action:@selector(handleLongPress:)]; 
    longPress.minimumPressDuration = iItemLongPressTime; 
    [self addGestureRecognizer:longPress]; 
    [longPress release]; 
} 
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) { 

     NSLog(@"Long press Ended"); 
    } 
    else { 
     NSLog(@"Long press detected."); 

     if (self.isSelected) return; 

     if ([delegate respondsToSelector:@selector(singleTouch:)]) 
      [delegate singleTouch:self]; 

     [sender removeTarget:self action:@selector(handleLongPress:)]; 
     sender.enabled = NO; 
     [self removeGestureRecognizer:sender]; 



    } 
} 

Saluti!

risposta

1

Ci sono due soluzioni nella mia mente.

  1. per animare UIView, si prega di scritto una nuova classe che viene ereditata dalla classe UIView e attuare le tocco delegati invece di scrivere i Gustures per gestire l'animazione (se il touch delegati non vengano attivati ​​nella classe corrente).

2. Ho rimosso con successo UILongPressGestureRecognizer dopo averlo attivato una volta.

Consultare il codice qui sotto mi .ask se avete domande

passaggi che ho fatto

Ho aggiunto un UIView come "myView" per il mio principale-view quando principale vista carichi .

Ho assegnato il tag al myView (è possibile assegnare 1,2,3 ... ecc.) Per differenziare la vista toccata dalle visualizzazioni secondarie della vista principale.

Assegnato il gesto UILongPressGestureRecognizer a myView e il target assegnato come metodo "moveMe".

Quando l'utente ha premuto a lungo myView, verrà attivato il metodo "moveMe".

Poi ho iterati le subviews MainView con la condizione Tag == 1

Ho rimosso l'UILongPressGestureRecognizer dalle subview.As possiamo sapere che Tagged 1 main-view visualizzazione secondaria è myView.

Quindi NSLog (@ "gesture rimosso"); e NSLog (@ "moveMe"); accederà alla console solo in una volta.

NSLog (@ "touchesBegan"); si innescherà per primo invece di attivare il metodo "moveMe".

Quindi NSLog (@ "touchesBegan"); si innescherà sempre dopo aver rimosso il gesto. il metodo "moveMe" non si innescherà mai.

Codice

- (void)viewDidLoad {  
     //Adding to UIView to main view when application is loading. 
     UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 80, 80)];   
     myView.backgroundColor = [UIColor viewFlipsideBackgroundColor]; 
      myView.tag = 1; //adding a tag to identify it. 
     //Adding Long Press Gesture to the UIView. 
     UILongPressGestureRecognizer *myGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(moveMe:)]; 
     [myView addGestureRecognizer:myGesture]; 
     [myGesture release]; 
     myGesture = nil; 
     [self.view addSubview:myView]; 
     [myView release]; 
     myView = nil;  
     [super viewDidLoad]; 
    }  

    //Method to trigger when user pressed long on the added UIView. 

-(void)moveMe:(id)sender 
{ 
     for (UIView *subViews in [self.view subviews]) 
     { 
      if (subViews.tag == 1) { 
       [subViews removeGestureRecognizer:sender]; 
       NSLog(@"gesture removed"); 
      }  
     }  
     NSLog(@"moveMe"); 
    }  
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"touchesBegan"); 
} 

o fare riferimento Disable gesture recognizer iOS

+0

Si prega di provare a descrivere la domanda in dettaglio –

+0

Ho provato l'invio per rimuovere il metodo il mittente come parametro, ma ancora non funziona. – NemeSys

+0

ho modificato la mia risposta ... –

4

Fa la classe UIView personalizzato dispone di un proprio codice di gestione tocco? In caso contrario, una soluzione semplice è impostare la proprietà su UILongPressGestureRecognizer su CGFLOAT_MAX o un numero grande e utilizzare le richiamate di aggiornamento gestuale per trascinare la visualizzazione personalizzata. È possibile ottenere lo spostamento utilizzando il metodo - (CGPoint)locationInView:(UIView *)view nella superview e confrontare la sua posizione con l'inizio del riconoscimento.

+1

+1 Questa è la soluzione più semplice. In sostanza, "Se utilizzi un riconoscitore di gesti, utilizza un riconoscitore di gesti". – NJones

+1

Non è necessario modificare la proprietà 'allowableMovement'; Viene usato solo per testare il fallimento. Dai commenti in "UILongPressGestureRecognizer.h" "Massimo movimento in pixel consentito prima che il gesto fallisca.Una volta riconosciuto (dopo minimumPressDuration) non c'è limite al movimento delle dita per il resto del tracciamento touch" " – NJones

+0

Ciao, grazie per le risposte . La sottoclasse di UIView implementa i touchBegan/Moved/Ended per manipolare le dimensioni e la posizione nella loro superview. L'uso dei gesti nasce dall'esigenza di rendere meno sensibile ai tocchi ogni oggetto. Al momento sto usando la soluzione di disabilitare l'oggetto gesture recognizer e funziona come un incantesimo. – NemeSys

Problemi correlati