2009-05-24 6 views
18

Sie wissen, wie Mario gerade weiter nach rechts läuft, wenn Sie die rechte Taste auf dem D-Pad gedrückt halten? Auf die gleiche Weise möchte ich, dass mein UIButton seine Aktion für die Dauer, in der es gedrückt wird, kontinuierlich auslöst. Ist dies für einen UIButton möglich? Wenn nicht, ist dies mit einem UIImageView möglich, indem eine Touch-Handling-Methode auf eine bestimmte Weise überschrieben wird? Vor dem Versuch, dies mit UIButton zu tun, hatte ich einige UIImageViews (die als D-Pad funktionieren), die durch Touch-Handling-Methoden überprüft wurden, aber die Dinge begannen unordentlich zu werden, also dachte ich, dies könnte mit UIButton einfacher gemacht werden gewechselt zu. Jeder, der weiß, wie man einen kontinuierlichen, stationären (nicht bewegten) Down-Touch erkennt, bitte teilen.Wie kann man einen UIButton während einer Press-and-Hold-Situation kontinuierlich brennen lassen?

Antwort

32

Sie keine Taste, verwenden Sie Multi-Touch und NSTimer:

Sie einen Blick lokalen NSTimer Objekt in Ihrer Schnittstelle, dann starten können/Abbrechen der 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; 
    } 
} 

Diese So können Sie das Ereignis in einem vordefinierten Intervall wiederholen und müssen sich nicht auf eine Schaltfläche verlassen, um das von Ihnen gewünschte Wiederholungsverhalten zu erhalten. Beachte den touchesMoved Trigger - wenn sie ihren Finger bewegen, wird der Timer abgebrochen und der Spieler stoppt die Bewegung.

+0

Sie haben 2 BerührungenBegan, ich glaube der 2. sollte touchesMoved sein. – freespace

+0

Großartig, obwohl Sie die doppelten BerührungenBegan Trigger zu Ihren beabsichtigten Berührungen korrigieren konnten, so dass niemand verwirrt wird. – RexOnRoids

40

Sie können auch ähnlich wie in der vorherigen Antwort und verwenden Sie immer noch eine UIButton.

Lassen Sie einfach den Timer auf "Touch Down" starten und lassen Sie den Timer entweder auf "Touch Up Inside" oder "Touch Up Outside" stoppen.

Persönlich mag ich die Verwendung von UIButtons, weil sie einige eingebaute visuelle Verbesserungen bieten, die Sie nicht selbst programmieren müssen.

+8

Nur um klar zu sein, sollten die Ereignisse "Touch Up Inside" und "Touch Up Outside" so konfiguriert werden, dass der Timer gestoppt wird. – gerry3

+1

Meiner Meinung nach besser als die ausgewählte Antwort. Kann über den Interface Builder konfiguriert werden. Außerdem führt die Arbeit mit IBActions in der Regel zu einem saubereren und leichter zu verstehenden Code als Berührungen und Anfänge. – txulu

+1

Vergessen Sie nicht, UIControlEventTouchCancel zu verwenden, wenn Sie diesen Ansatz befolgen. (Obwohl ich definitiv eine UIButton-Unterklasse empfehle, die NSTimer kapselt. View-Controller neigen dazu, zu groß zu sein, also alles, was Sie tun können, um den Code _out_ des View-Controllers zu verschieben, ist eine gute Sache.) –

2

Für mich sind die folgenden Werke:

  1. eine Schaltfläche erstellen.
  2. Erstellen Sie 2 Methoden (berühren Sie nicht mehr und beginnen Sie zu berühren), entweder im View-Controller oder in einer Unterklasse.
  3. Hinzufügen Steuerungsereignisse. Touch Up Inside und Touch Drag Exit, dass beide gehen, um die Methode zu berühren und berühren Touch Down geht mit der Methode zu berühren.
  4. Wenn die Methode start anfängt, sollten wir einen NSTimer mit einem Intervall von etwa 0,2 starten (es liegt an Ihnen, wie schnell Sie aufgerufen werden möchten), repeat und als Selektor eine Methode, die aufgerufen werden soll Dinge, die Sie ausführen möchten, wenn der Benutzer auf die Schaltfläche klickt).
  5. Wenn die Methode stop touch aufgerufen wird, sollten wir den Timer (.invalidate()) ungültig machen und den Timer als nil zuweisen.

Das ist alles!

0

Und jetzt für etwas ganz anderes:
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)") 
      } 
     }