2009-07-03 21 views
33

La mia app ha diversi pulsanti che attivano eventi diversi. L'utente NON deve essere in grado di tenere premuti diversi pulsanti. In ogni caso, tenendo premuti diversi pulsanti si blocca l'app.Come disabilitare il multitouch?

E così, sto provando a disabilitare il multi-tocco nella mia app.

Ho deselezionato 'Tocco multiplo' in tutti i file xib e, per quanto posso calcolare, le proprietà 'multipleTouchEnabled' e 'exclusiveTouch' controllano se la vista usa il multitouch. Così nel mio applicationDidFinishLaunching ho messo questo:

self.mainViewController.view.multipleTouchEnabled=NO; 
self.mainViewController.view.exclusiveTouch =YES; 

E in ciascuno dei miei controller di vista ho messo questo nella viewDidLoad

self.view.multipleTouchEnabled=NO; 
self.view.exclusiveTouch=YES; 

Tuttavia, è ancora accetta più tocchi. Potrei fare qualcosa come disabilitare altri pulsanti dopo aver ricevuto un evento di touch down, ma questo sarebbe un brutto scherzo. Sicuramente c'è un modo per disabilitare correttamente il multi-touch?

+0

Ho anche provato a fare lo stesso, ma ancora non in grado di farlo. Qualcuno sa come disabilitare la selezione di più ritmi in Cocos2D? –

+0

devi impostare 'exclusiveTouch = YES' su ciascun pulsante, non sulla vista. –

+0

Il problema principale che il tuo VIEW è single touch, ma non le subviews .. Quindi è necessario disabilitare i pulsanti, o per mettere una grande vista sui pulsanti e gestire il singolo tocco su di esso. – Jlexyc

risposta

43

Se si desidera un solo pulsante per rispondere ai tocchi alla volta, è necessario impostare exclusiveTouch per quel pulsante, anziché per la vista padre. In alternativa, è possibile disabilitare gli altri pulsanti quando un pulsante riceve l'evento "Touch Down".


Ecco un esempio di quest'ultimo, che ha funzionato meglio nei miei test. L'impostazione di exclusiveTouch per i pulsanti ha funzionato, ma ha causato alcuni problemi interessanti quando hai spostato il dito dal bordo di un pulsante, invece di fare clic su di esso.

È necessario disporre di prese nel controller collegate a ciascun pulsante e avere gli eventi "Touch Down", "Touch Up Inside" e "Touch Up Outside" collegati ai metodi corretti nel controller.

#import "multibuttonsViewController.h" 

@implementation multibuttonsViewController 

// hook this up to "Touch Down" for each button 
- (IBAction) pressed: (id) sender 
{ 
    if (sender == one) 
    { 
     two.enabled = false; 
     three.enabled = false; 
     [label setText: @"One"]; // or whatever you want to do 
    } 
    else if (sender == two) 
    { 
     one.enabled = false; 
     three.enabled = false; 
     [label setText: @"Two"]; // or whatever you want to do 
    } 
    else 
    { 
     one.enabled = false; 
     two.enabled = false; 
     [label setText: @"Three"]; // or whatever you want to do 
    } 
} 

// hook this up to "Touch Up Inside" and "Touch Up Outside" 
- (IBAction) released: (id) sender 
{ 
    one.enabled = true; 
    two.enabled = true; 
    three.enabled = true; 
} 

@end 
+3

Significa mettere button1.exclusiveTouch = YES; button2.exclusiveTouch = YES; button3.exclusiveTouch = YES; nel viewDidLoad del controller della vista? Ci ho provato - nessun effetto. – cannyboy

+4

Ho appena provato, e ha funzionato per me. È possibile che le prese viewController non siano impostate correttamente? Potrebbe valere la pena di controllare il debugger. –

+0

scuse. i pulsanti non erano collegati correttamente in IB – cannyboy

3

L'app si arresta in modo anomalo per un motivo. Indagare ulteriormente, utilizzare il debugger, vedere cosa c'è che non va, invece di cercare di nascondere il bug.

Edit:

OK, OK, devo ammettere che ero un po 'dura. Devi impostare la proprietà exclusiveTouch su ogni pulsante. È tutto. La proprietà multipleTouchEnabled è irrilevante.

+0

non sto cercando di nascondere il bug. l'utente non dovrebbe essere in grado di premere più pulsanti. – cannyboy

+0

Duro, sì. Ma anche corretto. exclusiveTouch deve essere impostato su ciascun pulsante, e in questo caso, con un bug che è probabilmente difficile da rintracciare senza informazioni dettagliate ... il debugger sarà il tuo migliore amico su questo. L'impostazione – mmc

+0

di ExclusiveTouch su ciascun pulsante non ha alcun effetto. – cannyboy

0

La mia esperienza è che, per impostazione predefinita, un nuovo progetto non consente nemmeno il multitouch, è necessario accenderlo. Ma suppongo che dipenda da come hai iniziato. Hai usato un esempio mutlitouch come modello?

Prima di tutto, sei assolutamente sicuro che il multitouch sia attivo? È possibile generare singoli tocchi in sequenza abbastanza rapidamente. Multitouch è più su ciò che fai con due o più dita una volta che sono in superficie. Forse hai un solo tocco, ma non gestisci correttamente ciò che accade se due pulsanti vengono premuti quasi allo stesso tempo.

+0

Il modello che sto usando è l'applicazione di utilità standard. Sì, forse è "un singolo tocco in sequenze" di cui dovrei essere preoccupato. Devo disabilitare tutti gli altri pulsanti quando si tiene premuto un tasto. Ma non sono ancora più vicino a una soluzione. – cannyboy

0

Ho appena avuto esattamente questo problema.

La soluzione siamo arrivati ​​a era semplicemente quello di ereditare una nuova classe da UIButton che l'override del metodo initWithCoder, e l'uso che dove abbiamo bisogno di uno pulsante alla volta (es.ovunque):

@implementation ExclusiveButton 

(id)initWithCoder: (NSCoder*)decoder 
{ 
    [self setExclusiveTouch:YES]; 
    return [super initWithCoder:decoder] 
} 

@end 

Si noti che questo funziona solo con i pulsanti caricati dai file pennino.

20
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    for(UIView* v in self.view.subviews) 
    { 
     if([v isKindOfClass:[UIButton class]]) 
     { 
      UIButton* btn = (UIButton*)v; 
      [btn setExclusiveTouch:YES]; 
     } 
    } 
} 
+0

estensione UIButton { aperta esclusione func touchesBegan (_ tocca: Set , con l'evento:? UIEvent) { eccellente. tocca Began (tocca, con: evento) self.isEnabled = false DispatchQueue.main.asyncAfter (scadenza: .ora() + 1) { self.isEnabled = true} }} –

0

Ho creato l'estensione di classe UIView e ho aggiunto queste due funzioni. e quando voglio disabilitare la visualizzazione tocco, chiamo [vedi makeExclusiveTouch];

- (void) makeExclusiveTouchForViews:(NSArray*)views { 
    for (UIView * view in views) { 
     [view makeExclusiveTouch]; 
    } 
} 

- (void) makeExclusiveTouch { 
    self.multipleTouchEnabled = NO; 
    self.exclusiveTouch = YES; 
    [self makeExclusiveTouchForViews:self.subviews]; 
} 
0

Se si desidera disattivare il multitouch di programmazione, o se si sta utilizzando cocos2d (nessuna opzione multipleTouchEnabled), è possibile utilizzare il seguente codice sul tuo ccTouches delegato:

- (BOOL)ccTouchesBegan:(NSSet *)touches 
withEvent:(UIEvent *)event { 
     NSSet *multiTouch = [event allTouches]; 
     if([multiTouch count] > 1) { 
      return; 
     } 
     else { 
      //else your rest of the code 
} 
5
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    for(UIView* v in self.view.subviews) 
    { 
     if([v isKindOfClass:[UIButton class]]) 
     { 
      UIButton* btn = (UIButton*)v; 
      [btn setExclusiveTouch:YES]; 
     } 
    } 
} 

Questo codice è testato e funziona perfettamente per me. Non c'è crash di app quando si preme più di un pulsante alla volta.

3

in base alla risposta del neoevoke, solo migliorare un po 'in modo che controlli anche i bambini subviews', ho creato questa funzione e aggiunsi al mio file utils:

// Set exclusive touch to all children 

+ (void)setExclusiveTouchToChildrenOf:(NSArray *)subviews 
{ 
    for (UIView *v in subviews) { 
     [self setExclusiveTouchToChildrenOf:v.subviews]; 
     if ([v isKindOfClass:[UIButton class]]) { 
      UIButton *btn = (UIButton *)v; 
      [btn setExclusiveTouch:YES]; 
     } 
    } 
} 

Poi, una chiamata semplice:

[Utils setExclusiveTouchToChildrenOf:self.view.subviews]; 

... farà il trucco.

0

disattivare tutti i pulsanti visibile in "Touch Down" evento e consentire loro nel "Touch Up Inside" evento.

ad esempio

- (void) handleTouchDown { 
    for (UIButton *btn in views) { 
     btn.enable = NO; 
    } 
} 

- (void) handleTouchUpInside { 
    for (UIButton *btn in views) { 
     btn.enable = Yes; 
    } 
    ------ 
    ------ 
} 
0

ho deciso questo problema in questo modo:

NSTimeInterval intervalButtonPressed; 

- (IBAction)buttonPicturePressed:(id)sender{ 

    if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) { 
     intervalButtonPressed = [[NSDate date] timeIntervalSince1970]; 
     //your code for button 
    } 
} 
3

Questo è spesso questione di essere segnalati dai nostri tester. Uno dei approccio che sto usando a volte, anche se dovrebbe essere usato consapevolmente, è quello di creare categoria per UIView, come questo:

@implementation UIView (ExclusiveTouch) 

- (BOOL)isExclusiveTouch 
{ 
    return YES; 
} 
+0

Argh! Perché questo non è abilitato di default ??? – jjxtra

-1

Basta impostare struttura tutto di UIView rilevanti exclusiveTouch false fare il trucco.

2

Per disabilitare multitouch in SWIFT:

È necessario prima ad avere una presa di ogni tasto e poi basta impostare il tocco esclusivo di true.Therefore in te viewDidLoad() avrebbe:

yourButton.exclusiveTouch = true.

// non è realmente necessario, ma si potrebbe anche aggiungere:

self.view.multipleTouchEnabled = false

0

avevo lottato con alcuni casi strani durante il trascinamento di oggetti intorno una vista, in cui se hai toccato un altro oggetto allo stesso tempo sarebbe licenziare i tocchi Metodo Began. La mia soluzione era quella di disabilitare l'interazione dell'utente per la vista genitore fino a quando touchEnded o touchesCancelled viene chiamato.

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    // whatever setup you need 
    self.view.userInteractionEnabled = false 
} 

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    // whatever setup you need 
    self.view.userInteractionEnabled = true 
} 

override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { 
    // whatever setup you need 
    self.view.userInteractionEnabled = true 
} 
1

Praticamente semplice è possibile utilizzare fare uso della proprietà ExclusiveTouch in questo caso

[youBtn setExclusiveTouch:YES]; 

Questo è un valore booleano che indica se il ricevitore gestisce gli eventi di tocco esclusivo.

L'impostazione di questa proprietà su SÌ consente al ricevitore di bloccare la consegna di eventi di tocco ad altre viste nella stessa finestra. Il valore predefinito di questa proprietà è NO.

Problemi correlati