Как я могу использовать NSTimer в Swift?
пробовал
var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
но, я получил сообщение об ошибке
'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
12 ответов:
это будет работать:
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 }
для Swift 4, метод которого вы хотите получить селектор должен быть подвержен Objective-C, таким образом
@objc
атрибут должен быть добавлен в объявление метода.
вот несколько более полных примеров, обновленных для Swift 3.
событие
вы можете использовать таймер для выполнения действия несколько раз, как показано в следующем примере. Таймер вызывает метод для обновления метки каждые полсекунды.
вот код:
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)" } }
отложенная событие
вы также можете использовать таймер для планирования однократного события на некоторое время в будущем. Основное отличие от приведенного выше примера заключается в том, что вы используете
repeats: false
вместоtrue
.timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
в приведенном выше примере вызывается метод с именем
delayedAction
через две секунды после таймера. Это не повторяется, но вы все равно можете позвонитьtimer.invalidate()
если вам нужно отменить событие, прежде чем это когда-либо произойдет.Примечания
- если есть шанс запустить экземпляр таймера несколько раз, убедитесь, что вы сначала аннулируете старый экземпляр таймера. В противном случае вы потеряете ссылку на таймер, и вы не можете остановить это. (см. это Q & A)
- не используйте таймеры, когда они не нужны. Смотрите раздел таймеры руководство по энергоэффективности для iOS-приложений.
по теме
обновлена Свифт 4, использование сведений о пользователях:
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) } }
С iOS 10 Существует также новый метод фабрики таймера на основе блока, который чище, чем использование селектора:
_ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in label.isHidden = true }
Swift 3, pre 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) } }
Примечания
- он должен быть в главной очереди
- функция обратного вызова может быть публичной, частной,...
- функция обратного вызова должна быть
@objc
регистрация с:
var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true);
вам нужно будет использовать таймер вместо NSTimer в Swift 3.
вот пример:
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 }
для swift 3 и Xcode 8.2 (приятно иметь блоки, но если вы компилируете для iOS9 и хотите userInfo):
...
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) }
SimpleTimer (Swift 3.1)
Почему?
это простой класс таймера в swift, который позволяет:
- локальный таймер
- Chainable
- одна вкладыши
- используйте регулярные обратные вызовы
использование:
SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs
код:
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() } }
In Swift 3 что-то вроде этого с @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() }
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
и создать удовольствие от имени createEnemy
fund createEnemy () { do anything //// }
Если вы инициализируете метод таймера
let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false) func update(_ timer : Timer) { }
затем добавьте его в цикл с помощью метода другой селектор не будет называться
RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)
Примечание: Если вы хотите, чтобы это повторилось, сделайте повторы true и сохраните ссылку таймера, иначе метод обновления не будет вызван.
Если вы используете этот метод.
Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)
сохранить ссылку для последующего использования, если повторяется-это правда.