2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Swift4】Timerで任意のインターバルで処理を実行する

Posted at

カウントした数値を画面に出す機能を作っている際、数値が0からカウントアップして今の数値になるアニメーションを実装したい場面に遭遇しました。

このような一定時間内に任意の間隔で処理を実行する場面はそこそこあるかと思ったので以下のクラスを作成しました。

CountTimer.swift

class CountTimer {
    
    private var timer: Timer?
    private let interval: Double
    private let execute_time: Double
    private var current_time: Double = 0.0
    
    init(count: Double, interval: Double, closure: @escaping (Double) -> Void) {
        self.execute_time = count
        self.interval = interval
        self.timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(CountTimer.timerUpdate), userInfo: closure, repeats: true)
        
    }
    
    @objc private func timerUpdate(_ timer: Timer!) {
        let closure =  timer.userInfo as! (Double) -> Void
        if current_time < execute_time {
            self.current_time += self.interval
            let percentage = floor(current_time / execute_time * 100) / 100
            closure(percentage)
        } else {
            self.invalidate()
        }
        
    }
    
    private func invalidate() {
        self.timer?.invalidate()
    }
}

実行する時間と実行間隔、処理内容のクロージャを渡し、一定の間隔で実行します。クロージャには全体の実行時間に対する現在のパーセンテージが小数点第二位までのDouble型で返すようにしてあります。
以下のように自分は使っています。

ViewController.swift

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        _ = CountTimer(count: 3.0, interval: 0.1) { percentage -> Void in
            print(percentage)
        }
    }
}

実行結果は以下のような感じです。全体3秒の処理を0.1秒間隔で実行しているため、一回につき0.03ずつ(1/30)増えていって、最後に1になっているのが確認できます。
image.png

冒頭で書いたLabelへのアニメーションは以下のような感じで使っています。値を受け取ったら3秒かけて0.05秒ごとに数値をカウントアップする処理が書けました。

ViewController.swift
class ViewController: UIViewController {
    @IBOutlet weak var countLabel: UILabel!    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        ...
        
        viewModel?.stepCount.observeNext { (value: Double) -> Void in
            _ = StepTimer(count: 3.0, interval: 0.05) { percentage -> Void in
                let count = value * percentage
                self.countLabel.text = String(count)
            }
        }
    }        
}

2
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?