2009-05-24 7 views
18

Sai come Mario continua a correre a destra quando premi e tieni premuto il tasto destro sul D-Pad? Allo stesso modo, voglio che il mio UIButton attivi continuamente la sua azione per tutta la durata in cui viene tenuto premuto. È possibile per un UIButton? In caso contrario, è possibile farlo con UIImageView sovrascrivendo un metodo di gestione del tocco in un determinato modo? In realtà, prima di provare a fare questo con UIButton, avevo alcune UIImageViews (disposte per funzionare come un D-Pad) che venivano controllate dai metodi di gestione touch ma le cose cominciavano a diventare disordinate quindi pensavo che questo potesse essere fatto più facilmente con UIButton e quindi cambiato. Chiunque sappia come ottenere il riconoscimento di un down-touch continuo, fermo (non commosso), si prega di condividere.Modo per far sparare un UIButton in modo continuo durante una situazione di attesa e risposta?

risposta

32

Non utilizzare un pulsante, utilizzare multi-touch e NSTimer:

Fai un oggetto NSTimer vista locale all'interno della vostra interfaccia, quindi utilizzarlo per avviare/annullare il timer

-(void)movePlayer:(id)sender { 
    <Code to move player> 
} 

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 
    timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(movePlayer:) userInfo:nil repeats:YES]; 
} 

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { 
    if (timer != nil) 
     [timer invalidate]; 
     timer = nil; 
} 

-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 
    if (timer != nil) { 
     [timer invalidate]; 
     timer = nil; 
    } 
} 

Questo modo, è possibile ripetere l'evento a intervalli predefiniti, senza dover contare su un pulsante e ottenere il comportamento di ripetizione che si sta cercando. Nota il grilletto attivato - se muovono il dito, questo annulla il timer e il giocatore smette di muoversi.

+0

Hai 2 tocchi Began, credo che il 2 ° tocchi dovrebbe essere rimosso. – freespace

+0

Grande, anche se potessi correggere i tocchi duplicati. Innesco Began ai tuoi tocchi preferiti. Spostati in modo che nessuno si confonda. – RexOnRoids

40

È inoltre possibile eseguire operazioni simili a quelle mostrate nella risposta precedente e utilizzare ancora un UIButton.

Basta avviare il timer sul "Touch Down" e far arrestare il timer su "Ritocco interno" o "Ritocco esterno".

Personalmente, mi piace usare gli UIButton perché offrono alcuni miglioramenti visivi integrati che non è necessario codificare autonomamente.

+8

Giusto per essere chiari, entrambi gli eventi "Touch Up Inside" e "Touch Up Outside" devono essere configurati per fermare il timer. – gerry3

+1

A mio parere, una risposta migliore rispetto a quella selezionata. Può essere configurato tramite il generatore di interfacce. Inoltre, lavorare con IBActions di solito porta a un codice più pulito e più facile da capire rispetto a quello che si usa per iniziare e friggere. – txulu

+1

Non dimenticare di gestire UIControlEventTouchCancel se si scende a questo approccio. (Anche se consiglio vivamente una sottoclasse UIButton che incapsula NSTimer. I controller di visualizzazione tendono ad essere troppo grandi, quindi tutto ciò che puoi fare per spostare il codice _out_ del controller di visualizzazione è una buona cosa.) –

2

Per me le seguenti opere:

  1. creare un pulsante.
  2. Creare 2 metodi (smettere di toccare e iniziare a toccare) nel controller di visualizzazione o in una sottoclasse.
  3. Aggiungi Eventi di controllo. Ritocco interno e Toccare Trascinare Esci che entrambi vanno a smettere di toccare il metodo e Toccare Giù con il metodo di tocco iniziale.
  4. Quando si inizia a toccare il metodo invocato dovremmo avviare un NSTimer con intervallo di circa 0,2 (dipende da voi quanto velocemente si vorrebbe essere richiamati), ripetere true e come selettore un metodo che si desidera richiamare (con l'effettivo cose che vuoi eseguire quando l'utente preme il pulsante).
  5. Quando si smette di toccare il metodo invocato, è necessario invalidare il timer (.invalidate()) e assegnare il timer come nullo.

Questo è tutto!

0

E ora qualcosa di completamente diverso:
ReactiveCocoa 6.

self.button.reactive 
    .controlEvents([.touchDown]) 
    .observeValues { button in 
     SignalProducer.timer(interval: .milliseconds(500), on: QueueScheduler.main) 
      .take(until: button.reactive.controlEvents([.touchDragOutside, .touchDragExit, .touchUpInside, .touchUpOutside, .touchCancel]).map { _ in return }) 
      .prefix(value: Date()) 
      .startWithValues { date in 
       NSLog("\(date)") 
      } 
     }