簡體   English   中英

迅速創建獨立的計時器

[英]Swift creation of separate timers

我正在嘗試制作連接到按鈕的倒計時器,並且我正在使用

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)

但是,我想要它,所以如果我按下相同的按鈕,新的計時器以相似的設置開始,所以在控制台中有2個,3個等倒計時器同時進行。 每當我按下按鈕時,如果按照與前一個相同的設置生成新計時器,但是舊計時器仍處於活動狀態並且正在關閉,我該怎么做?

要跟蹤各種計時器,您需要創建一個計時器數組( [Timer] )並創建一個TimerState作為userInfo對象傳遞到每個計時器。 然后,當調用updateTimer()時,您可以將該計時器的state作為timer.userInfo並使用它。 當計時器達到0 ,調用invalidate()並將其從計時器列表中刪除。

如果用戶按下Stop All Timers按鈕,則使用timers數組停止所有活動計時器。

import UIKit

class TimerState {
    let number: Int
    var count: Int

    init(number: Int, count: Int) {
        self.number = number
        self.count = count
    }
}

class ViewController: UIViewController {

    var timerNumber = 1
    var startingCount = 10

    // Array to hold active timers so that all can be stopped
    var timers = [Timer]()

    @IBAction func startTimer(_ sender: UIButton) {
        let state = TimerState(number: timerNumber, count: startingCount)

        let timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: state, repeats: true)

        timers.append(timer)

        timerNumber += 1
    }

    @objc func updateTimer(_ timer: Timer) {
        guard let state = timer.userInfo as? TimerState else { return }
        state.count -= 1
        if state.count == 0 {
            print("Timer \(state.number) is done")
            timer.invalidate()

            // remove this timer from the list of active timers
            if let index = timers.firstIndex(of: timer) {
                timers.remove(at: index)
            }
        } else {
            print("Timer \(state.number): \(state.count)")
        }
    }

    @IBAction func stopAllTimers(_ sender: UIButton) {
        for timer in timers {
            guard let state = timer.userInfo as? TimerState else { continue }
            print("Timer \(state.number) stopped")

            timer.invalidate()
        }
    }
}

按下Start Timer按鈕3次會在控制台中產生以下輸出:

 Timer 1: 9 Timer 1: 8 Timer 1: 7 Timer 2: 9 Timer 1: 6 Timer 2: 8 Timer 1: 5 Timer 2: 7 Timer 3: 9 Timer 1: 4 Timer 2: 6 Timer 3: 8 Timer 1: 3 Timer 2: 5 Timer 3: 7 Timer 1: 2 Timer 2: 4 Timer 3: 6 Timer 1: 1 Timer 2: 3 Timer 3: 5 Timer 1 is done Timer 2: 2 Timer 3: 4 Timer 2: 1 Timer 3: 3 Timer 2 is done Timer 3: 2 Timer 3: 1 Timer 3 is done 

根據您的代碼:

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)

我假設您在ViewController中將timer聲明為實例變量,例如:

class ViewController: UIViewController {
    var timer: Timer?

    @IBAction func tapped(_ sender: Any) {
        timer?.invalidate()

        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
    }

    @objc func clock() {
        print("counting...")
    }
}

因此,每按一下按鈕,即使您使用相同的Timer實例,它也會安排新的計時會話。 在這種情況下,您應該做的是每次在Timer.scheduledTimer分配Timer.scheduledTimer之前使 timer 無效

停止計時器再次發射並請求從其運行循環中刪除它。

在按鈕操作方法中,在第一個中添加timer?.invalidate()

@IBAction func tapped(_ sender: Any) {
    timer?.invalidate()

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
}

為每個按下按鈕(如果確實需要多個計時器)創建一個具有相同屬性的新Timer()實例。

值得保留所有計時器的列表,因此當你不再需要它們時你可以處理它們(所以如果有人發送垃圾按鈕,你就不會有很多計時器)。

嗯,這取決於你是否需要跟蹤所有這些計時器。 如果不是非常簡單。 只需在每次單擊按鈕時創建一個計時器:

func buttonDidClick() {
    Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
}

如果你需要跟蹤那些計時器使用數組:

func buttonDidClick() {
        myArray.append(Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true))
    }

這樣您甚至可以取消所有計時器或做任何您需要的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM