ios 如何在 Swift 中使用 Timer(以前称为 NSTimer)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24007518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:17:01  来源:igfitidea点击:

How can I use Timer (formerly NSTimer) in Swift?

iosnstimernstimeintervalswift

提问by user3225917

I tried

我试过

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

But, I got an error saying

但是,我有一个错误说

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

回答by Oscar Swanros

This will work:

这将起作用:

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
}

For Swift 4, the method of which you want to get the selector must be exposed to Objective-C, thus @objcattribute must be added to the method declaration.

对于 Swift 4,您要获取选择器的方法必须暴露给 Objective-C,因此@objc必须将属性添加到方法声明中。

回答by Suragch

Repeated event

重复事件

You can use a timer to do an action multiple times, as seen in the following example. The timer calls a method to update a label every half second.

您可以使用计时器多次执行操作,如以下示例所示。计时器每半秒调用一个方法来更新一个标签。

enter image description here

在此处输入图片说明

Here is the code for that:

这是代码:

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)"
    }
}

Delayed event

延迟事件

You can also use a timer to schedule a one time event for some time in the future. The main difference from the above example is that you use repeats: falseinstead of true.

您还可以使用计时器来安排将来某个时间的一次性事件。与上述示例的主要区别在于您使用了repeats: false而不是true.

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

The above example calls a method named delayedActiontwo seconds after the timer is set. It is not repeated, but you can still call timer.invalidate()if you need to cancel the event before it ever happens.

上面的示例delayedAction在设置计时器后两秒调用一个名为的方法。它不会重复,但timer.invalidate()如果您需要在事件发生之前取消它,您仍然可以调用。

Notes

笔记

  • If there is any chance of starting your timer instance multiple times, be sure that you invalidate the old timer instance first. Otherwise you lose the reference to the timer and you can't stop it anymore. (see this Q&A)
  • Don't use timers when they aren't needed. See the timers section of the Energy Efficiency Guide for iOS Apps.
  • 如果有机会多次启动您的计时器实例,请确保首先使旧计时器实例无效。否则,您将失去对计时器的引用,并且无法再停止它。(请参阅此问答
  • 不要在不需要时使用计时器。请参阅iOS 应用程序能效指南的计时器部分。

Related

有关的

回答by igraczech

Updated to Swift 4, leveraging userInfo:

更新到 Swift 4,利用 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)
    }

}

回答by Josh Homann

As of iOS 10 there is also a new block based Timer factory method which is cleaner than using the selector:

从 iOS 10 开始,还有一个新的基于块的 Timer 工厂方法,它比使用选择器更简洁:

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

回答by onmyway133

Swift 3, pre iOS 10

Swift 3,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+

斯威夫特 3,iOS 10+

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

Notes

笔记

  • It needs to be on the main queue
  • Callback function can be public, private, ...
  • Callback function needs to be @objc
  • 它需要在主队列中
  • 回调函数可以是公共的、私有的、......
  • 回调函数需要 @objc

回答by Midhun MP

Check with:

检查:

Swift 2

斯威夫特 2

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

Swift 3, 4, 5

斯威夫特 3、4、5

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

回答by Ondrej Kvasnovsky

You will need to use Timerinstead of NSTimer in Swift 3.

您将需要在 Swift 3 中使用Timer而不是 NSTimer。

Here is an example:

下面是一个例子:

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
}

回答by Wissa

Swift 5

斯威夫特 5

I personally prefer the Timer with the block closure:

我个人更喜欢带有块关闭的计时器:

    Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
       // TODO: - whatever you want
    }

回答by ingconti

for swift 3 and Xcode 8.2 (nice to have blocks, but if You compile for iOS9 AND want userInfo):

对于 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)
    }

回答by eonist

SimpleTimer (Swift 3.1)

SimpleTimer (Swift 3.1)

Why?

为什么?

This is a simple timer class in swift that enables you to:

这是一个简单的 swift 计时器类,它使您能够:

  • Local scoped timer
  • Chainable
  • One liners
  • Use regular callbacks
  • 本地范围定时器
  • 可链接
  • 一个班轮
  • 使用常规回调

Usage:

用法:

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()
    }
}