如何在Swift中使用NSTimer?

use*_*917 246 nstimer nstimeinterval ios swift

我试过了

var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
Run Code Online (Sandbox Code Playgroud)

但是,我说错了

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

Osc*_*ros 522

这将有效:

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
}
Run Code Online (Sandbox Code Playgroud)

对于Swift 4,您希望获取选择器的方法必须公开给Objective-C,因此@objc必须将属性添加到方法声明中.

  • 从Xcode 6.1开始,我不得不将"@objc"添加到函数头中,如下所示:"@ objc func update(){".如果没有它,应用程序会在第一次火灾时崩溃. (27认同)
  • 确保`update()`函数不是`private` (3认同)
  • 我想补充说,使用这些方法的类需要是一个NSObject,否则你最终会得到一个无法识别的选择器错误 (2认同)
  • 块语法的一个可能更有用的版本: let timer = Timer.scheduledTimer(withTimeInterval: timeout, Repeats: false) { _ in print("Done.") } (2认同)
  • 您不能使用 'let timer = Timer(timeInterval: 0.4, Repeats: true) { _ in print("Done!") }' 这不会启动计时器,然后您就无法让它重复。您必须使用 Timer.scheduledTimer。 (2认同)

Sur*_*gch 144

重复的事件

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

在此输入图像描述

这是代码:

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)"
    }
}
Run Code Online (Sandbox Code Playgroud)

延迟事件

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

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

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

笔记

  • 如果有可能多次启动计时器实例,请确保先使旧计时器实例无效.否则你将失去对计时器的引用,你不能再停止它了.(见这个问答)
  • 不需要时使用计时器.请参阅"iOS应用能源效率指南"中的计时器部分.

有关


igr*_*ech 30

更新到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)
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 展示一个工作示例,如果函数期望"NSTimer"对象,"自定义"和"数据"意味着什么 (2认同)

Jos*_*ann 27

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

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

  • 如果您使有关未使用值的警告静音,或者您只是不关心警告,则可以省略 _ =。我不喜欢检查带有警告的代码。 (2认同)

onm*_*133 21

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)
  }
Run Code Online (Sandbox Code Playgroud)

Swift 3,iOS 10+

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

笔记

  • 它需要在主队列中
  • 回调函数可以是公共的,私有的,...
  • 需要回调函数 @objc


Mid*_* MP 17

检查:

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

  • 我已经尝试了但是它说'找不到接受提供的参数'init'的重载' (2认同)

Ond*_*sky 11

你需要在Swift 3中使用Timer而不是NSTimer.

这是一个例子:

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
}
Run Code Online (Sandbox Code Playgroud)


Wis*_*ssa 8

迅捷5

我个人更喜欢带有封闭块的Timer:

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


ing*_*nti 7

对于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)
    }
Run Code Online (Sandbox Code Playgroud)


gen*_*ius 7

首先声明你的计时器

var timer: Timer?
Run Code Online (Sandbox Code Playgroud)

然后在 viewDidLoad() 或要启动计时器的任何函数中添加行

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(action), userInfo: nil, repeats: false)
Run Code Online (Sandbox Code Playgroud)

这是您将回调它以执行某些操作的函数,它必须是@objc

@objc func action () {
print("done")
}
Run Code Online (Sandbox Code Playgroud)


eon*_*ist 5

SimpleTimer(Swift 3.1)

为什么?

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

  • 本地范围的计时器
  • 可链接
  • 一个衬里
  • 使用常规回调

用法:

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

码:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)