2012-08-25 11 views
10

Sto riscontrando un problema con la gestione di più di un tocco tramite i metodi Began/Moved/Ended di UIViewController. Sto anche assistendo allo stesso comportamento in un'app cocos2d (usando ccTouchesBegan/Moved/Ended) quindi penso che questa domanda possa essere applicata a tutti i touch di iOS. Ho messo il codice che sto usando qui sotto, seguito dai risultati che sto vedendo.Perché tocca UIViewControllerBegan, toccaMoved e toccaEnded viene chiamato solo quando inizia il primo dei due tocchi, si sposta o termina?

Tutti i metodi sono implementati su una sottoclasse UIViewController.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"Touches Began"); 
    [self logTouchesFor: event]; 

    [super touchesEnded: touches withEvent: event]; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"Touches Moved"); 
    [self logTouchesFor: event]; 

    [super touchesEnded: touches withEvent: event]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    NSLog(@"Touches Ended"); 
    [self logTouchesFor: event]; 

    [super touchesEnded: touches withEvent: event]; 
} 

-(void)logTouchesFor:(UIEvent *)event 
{ 
    int count = 1; 

    for (UITouch *touch in event.allTouches) 
    { 
     CGPoint location = [touch locationInView: self.view]; 

     NSLog(@"%d: (%.0f, %.0f)", count, location.x, location.y); 
     count++; 
    } 
} 

Ora per i risultati interessanti ...

Tocchi singola opera come previsto

Diciamo che toccare lo schermo con il pollice. Vedo nella finestra di output che tocca Began è stato chiamato come previsto. Mi muovo il pollice e tocco viene chiamato Moved. Quindi tolgo il pollice dallo schermo e tocco viene chiamato. Tutto questo è come previsto, lo includo nella domanda come un caso di controllo - solo per essere chiaro che il mio controller di visualizzazione sta ricevendo eventi touch e non ho perso uno vc.view.userInteractionEnabled = YES ovunque.

Il secondo tocco non causa touchesBegan, touchesMoved o touchesEnded di essere chiamato

Questo è il più interessante. Diciamo che tocco lo schermo con il pollice (tocca Began è chiamato) e lo tengo fermo sullo schermo. Poi tocco altrove sullo schermo con il mio indice, mantenendo il mio pollice nello stesso punto. TouchesBegan non viene chiamato. Quindi diciamo che muovo il dito indice mantenendo il mio pollice assolutamente fermo (questo può essere difficile ma è possibile). TouchesMoved non viene chiamato. Quindi, tolgo l'indice dallo schermo. TouchesEnded non viene chiamato. Alla fine, sposto il pollice e tocchi che viene chiamato Move. Quindi alzo il pollice dallo schermo e tocchi chiamato Ended.

Giusto per essere chiari: ho impostato self.view.multipleTouchEnabled = YES nel mio metodo viewDidLoad.

informazioni sui Seconda Touch è disponibile, fornendo la prima tocco si sposta

Questa volta che faccio qualcosa di molto simile all'esempio immediatamente sopra. Tocco lo schermo con il pollice, poi con l'indice mantenendo il mio pollice fermo. TouchesBegan viene chiamato quando il mio pollice colpisce lo schermo, ma non il mio indice. Ora sposto il mio pollice e viene chiamato Moved. Non solo, ma ci sono due tocchi nell'evento. AllTouches array (e sì, il secondo tocco è dove mi aspetterei che sia). Ciò significa che il sistema è consapevole del fatto che ho toccato lo schermo una seconda volta, ma non mi viene notificato tramite i metodi di gestione del tocco sul mio controller di visualizzazione.

Come posso essere informato sulle modifiche al secondo tocco?

Mi piacerebbe davvero essere in grado di rispondere ai cambiamenti nella posizione o stato del secondo tocco mentre accadono, piuttosto che quando cambia anche il primo tocco. Molto spesso questo non sarà un problema, perché è molto difficile cambiare un tocco senza influire sull'altro, ma ho almeno una situazione in cui può essere un problema. Mi manca qualcosa di ovvio? Qualcun altro ha notato questo comportamento o ha avuto problemi con esso?

Nel caso sia rilevante, sto usando un iPhone 3GS con iOS 5.1.

+0

hai 'exclusiveTouch = YES'somewhere nella tua gerarchia di viste? Questo sembra accadere per me quando il primo tocco è in una sottoview di una vista con 'exclusiveTouch = YES' –

+0

Non lo metto da nessuna parte nel codice, ma sto usando gli storyboard - potrebbero averlo impostato da qualche parte? C'è qualche altra proprietà che potrebbe avere un effetto simile? Questo controller di visualizzazione ha alcune generazioni in profondità nella gerarchia della vista, quindi una delle sue visualizzazioni potrebbe fare qualcosa che non mi aspetto. – rankAmateur

+1

potrebbe essere che sono in ritardo ma hai notato che in ogni metodo il super chiamato è lo stesso: touchEnded – advantej

risposta

11

Ok, ho iniziato faticosamente ricostruendo il mio progetto, aggiungendo i file uno alla volta, e credo di aver capito ...

C'era una visualizzazione secondaria della vista in questione, che aveva userInteractionEnabled == YES. Una volta impostato su NO, il controller di visualizzazione ha iniziato a ricevere le chiamate di inizio/fine/fine/fine per ciascun tocco. Presumibilmente, il secondo tocco veniva rivendicato dalla sottoview e non lo rendeva al mio controller di visualizzazione, ma non ho idea del motivo per cui ciò avverrebbe solo con il secondo tocco e non il primo.

Non ho ancora capito cosa sta succedendo con il progetto cocos2d, ma presumibilmente è un problema diverso in quanto non ci sono subviews o nodi che potrebbero fare la stessa cosa.

+3

È possibile che la tua sottoview abbia multipleTouchEnabled == NO? –

+0

Sì, lo ha fatto, ma ancora non capisco perché ci sia voluto il secondo tocco piuttosto che il primo. – rankAmateur

+5

Stai chiamando i tocchiEnd super metodo nei tuoi tocchi Metodo Began. Dovresti chiamare super-touchBegan. (e viceversa per i touchMoved) – Toad

Problemi correlati