web-dev-qa-db-ja.com

SwiftでNSTimerを使用する方法

私は試した

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'
233
user3225917

これは動作します:

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属性をメソッド宣言に追加する必要があります。

510
Oscar Swanros

繰り返しイベント

次の例に示すように、タイマーを使用してアクションを複数回実行できます。タイマーは、0.5秒ごとにラベルを更新するためのメソッドを呼び出します。

enter image description here

そのためのコードは次のとおりです。

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

遅延イベント

また、将来のしばらくの間ワンタイムイベントをスケジュールするためにタイマーを使用することもできます。上記の例との主な違いは、trueの代わりにrepeats: falseを使用することです。

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

上記の例は、タイマーが設定されてから2秒後にdelayedActionという名前のメソッドを呼び出します。繰り返されることはありませんが、発生する前にイベントをキャンセルする必要がある場合はtimer.invalidate()を呼び出すことができます。

ノート

  • タイマーインスタンスを複数回起動する可能性がある場合は、最初に古いタイマーインスタンスを無効にしてください。そうでなければあなたはタイマーへの参照を失い、あなたはもうそれを止めることはできません。 ( このQ&A を参照)
  • 不要なときはタイマーを使用しないでください。 iOSアプリのエネルギー効率ガイド のタイマーセクションを参照してください。

関連する

136
Suragch

UserInfoを利用して、Swift 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)
    }

}
27
igraczech

IOS 10以降、セレクタを使用するよりもクリーンな、新しいブロックベースのTimerファクトリメソッドもあります。

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

IOS 10より前のSwift 3

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である必要があります
19
onmyway133

確認する:

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

Swift 3ではNSTimerの代わりに Timer を使う必要があります。

これが一例です。

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
}
10

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)
    }
6
ingconti

SimpleTimer(スウィフト3.1)

どうして?

これはSwiftのシンプルなタイマークラスで、以下のことが可能です。

  • ローカルスコープタイマー
  • チェーン可能
  • ワンライナー
  • 通常のコールバックを使う

使用法:

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

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()
}
2
Nik Kov
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)

そしてcreateEnemyという名前で楽しもう

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

タイマーのメソッドを起動した場合

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)

注:これを繰り返してほしい場合はmake repeatをtrueにしてtimerの参照を保持してください。そうしないとupdateメソッドは呼び出されません。

この方法を使用している場合.

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

繰り返しが正しい場合は、後で使用するために参照を保管してください。

1
Surjeet Rajput