web-dev-qa-db-de.com

Wie kann ich Timer (früher NSTimer) in Swift verwenden?

Ich habe es versucht

var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)

Aber ich habe eine Fehlermeldung bekommen

'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
239
user3225917

Das wird funktionieren:

override func viewDidLoad() {
    super.viewDidLoad()
    // Swift block syntax (iOS 10+)
    let timer = Timer(timeInterval: 0.4, repeats: true) { _ in print("Done!") }
    // Swift >=3 selector syntax
    let timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
    // Swift 2.2 selector syntax
    let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
    // Swift <2.2 selector syntax
    let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
}

// must be internal or public. 
@objc func update() {
    // Something cool
}

Für Swift 4 muss die Methode, von der Sie den Selektor erhalten möchten, Objective-C ausgesetzt werden. Daher muss das @objc -Attribut zur Methodendeklaration hinzugefügt werden.

514
Oscar Swanros

Wiederholtes Ereignis

Sie können einen Timer verwenden, um eine Aktion mehrmals auszuführen, wie im folgenden Beispiel gezeigt. Der Timer ruft eine Methode zum Aktualisieren eines Etiketts jede halbe Sekunde auf.

enter image description here

Hier ist der Code dafür:

import UIKit

class ViewController: UIViewController {

    var counter = 0
    var timer = Timer()

    @IBOutlet weak var label: UILabel!

    // start timer
    @IBAction func startTimerButtonTapped(sender: UIButton) {
        timer.invalidate() // just in case this button is tapped multiple times

        // start the timer
        timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    }

    // stop timer
    @IBAction func cancelTimerButtonTapped(sender: UIButton) {
        timer.invalidate()
    }

    // called every time interval from the timer
    func timerAction() {
        counter += 1
        label.text = "\(counter)"
    }
}

Verspätetes Ereignis

Sie können auch einen Timer verwenden, um ein einmaliges Ereignis für eine bestimmte Zeit in der Zukunft zu planen. Der Hauptunterschied zum obigen Beispiel besteht darin, dass Sie repeats: false anstelle von true verwenden.

timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)

Das obige Beispiel ruft eine Methode namens delayedAction zwei Sekunden nach dem Einstellen des Timers auf. Es wird nicht wiederholt, aber Sie können immer noch timer.invalidate() aufrufen, wenn Sie das Ereignis abbrechen müssen, bevor es jemals passiert.

Anmerkungen

  • Wenn die Möglichkeit besteht, dass Ihre Zeitgeberinstanz mehrmals gestartet wird, stellen Sie sicher, dass Sie zuerst die alte Zeitgeberinstanz ungültig machen. Andernfalls verlieren Sie den Bezug zum Timer und können ihn nicht mehr anhalten. (siehe diese Q & A )
  • Verwenden Sie keine Timer, wenn sie nicht benötigt werden. Weitere Informationen finden Sie im Abschnitt Timer im Energieeffizienzhandbuch für iOS-Apps .

Verbunden

141
Suragch

Auf Swift 4 aktualisiert, unter Nutzung von userInfo:

class TimerSample {

    var timer: Timer?

    func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 5.0,
                                     target: self,
                                     selector: #selector(eventWith(timer:)),
                                     userInfo: [ "foo" : "bar" ],
                                     repeats: true)
    }

    // Timer expects @objc selector
    @objc func eventWith(timer: Timer!) {
        let info = timer.userInfo as Any
        print(info)
    }

}
29
igraczech

Ab iOS 10 gibt es auch eine neue blockbasierte Timer-Factory-Methode, die sauberer ist als die Verwendung des Selektors:

    _ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
        label.isHidden = true
    }
25
Josh Homann

Swift 3, vor iOS 10

func schedule() {
    DispatchQueue.main.async {
      self.timer = Timer.scheduledTimer(timeInterval: 20, target: self,
                                   selector: #selector(self.timerDidFire(timer:)), userInfo: nil, repeats: false)
    }
  }

  @objc private func timerDidFire(timer: Timer) {
    print(timer)
  }

Swift 3, iOS 10+

DispatchQueue.main.async {
      self.timer = Timer.scheduledTimer(withTimeInterval: 20, repeats: false) { timer in
        print(timer)
      }
    }

Anmerkungen

  • Es muss sich in der Hauptwarteschlange befinden
  • Rückruffunktion kann öffentlich, privat, ... sein.
  • Rückruffunktion muss @objc sein
20
onmyway133

Erkundigen Sie sich bei:

Swift 2

var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)

Swift 3, 4, 5

var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
15
Midhun MP

Sie müssen Timer anstelle von NSTimer in Swift 3 verwenden.

Hier ist ein Beispiel:

Timer.scheduledTimer(timeInterval: 1, 
    target: self, 
    selector: #selector(YourController.update), 
    userInfo: nil, 
    repeats: true)

// @objc selector expected for Timer
@objc func update() {
    // do what should happen when timer triggers an event
}
11

für Swift 3 und Xcode 8.2 (Schön, Blöcke zu haben, aber wenn Sie für iOS9 kompilieren UND userInfo möchten):

...

        self.timer = Timer(fireAt: fire,
                           interval: deltaT,
                           target: self,
                           selector: #selector(timerCallBack(timer:)),
                           userInfo: ["custom":"data"],
                           repeats: true)

        RunLoop.main.add(self.timer!, forMode: RunLoopMode.commonModes)
        self.timer!.fire()
}

func timerCallBack(timer: Timer!){
        let info = timer.userInfo
        print(info)
    }
6
ingconti

SimpleTimer (Swift 3.1)

Warum?

Dies ist eine einfache Timer-Klasse in Swift, mit der Sie:

  • Zeitgeber mit lokalem Gültigkeitsbereich
  • Verkettbar
  • Einzeiler
  • Verwenden Sie regelmäßige Rückrufe

Verwendungszweck:

SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs

Code:

class SimpleTimer {/*<--was named Timer, but since Swift 3, NSTimer is now Timer*/
    typealias Tick = ()->Void
    var timer:Timer?
    var interval:TimeInterval /*in seconds*/
    var repeats:Bool
    var tick:Tick

    init( interval:TimeInterval, repeats:Bool = false, onTick:@escaping Tick){
        self.interval = interval
        self.repeats = repeats
        self.tick = onTick
    }
    func start(){
        timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(update), userInfo: nil, repeats: true)//Swift 3 upgrade
    }
    func stop(){
        if(timer != nil){timer!.invalidate()}
    }
    /**
     * This method must be in the public or scope
     */
    @objc func update() {
        tick()
    }
}
5
eonist

In Swift so etwas mit @objc:

func startTimerForResendingCode() {
    let timerIntervalForResendingCode = TimeInterval(60)
    Timer.scheduledTimer(timeInterval: timerIntervalForResendingCode,
                         target: self,
                         selector: #selector(timerEndedUp),
                         userInfo: nil,
                         repeats: false)
}




@objc func timerEndedUp() {
    output?.timerHasFinishedAndCodeMayBeResended()
}
2
Nik Kov
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)

Und erstellen Sie Spaß mit dem Namen createEnemy

fund createEnemy ()
{
do anything ////
}
2
Khaled Hamdy

Wenn Sie die Timer-Methode starten

let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)

func update(_ timer : Timer) {

}

fügen Sie es dann mit einer anderen Methode zur Schleife hinzu. Der Selektor wird nicht aufgerufen

RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)

HINWEIS: Wenn Sie möchten, dass dies wiederholt wird, machen Sie Wiederholungen wahr und behalten Sie die Referenz des Timers bei, da sonst die Aktualisierungsmethode nicht aufgerufen wird.

Wenn Sie diese Methode verwenden.

Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)

bewahren Sie eine Referenz für eine spätere Verwendung auf, wenn Wiederholungen zutreffen.

1
Surjeet Rajput