簡體   English   中英

來自 ViewController 的 Swift 調用計時器

[英]Swift call timer from ViewController

我有一個 TimerManager 類,我想在多個ViewControllers訪問它,但我想不出一個好的方法。 我的代碼如下:

class TimerManager {

    private var timer: NSTimer
    private var timeRemaining: Int

    init(initialTime: Int) {
        self.timer = NSTimer()
        self.timeRemaining = initialTime
    }

    func startTimer() {
        self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(TimerManager.update), userInfo: nil, repeats: true)
    }

    func endTimer() {
        self.timer.invalidate()
    }

    func getTimeRemaining() -> Int {
        return self.timeRemaining
    }

    @objc func update() {
        if self.timeRemaining > 0 {
            self.timeRemaining = self.timeRemaining - 1
        }
        else {
            endTimer()
        }
    } 
}

在我的ViewController我希望能夠訪問我的update()函數來更新我的實際頁面上的計時器(這是一個UILabel ),但是由於我的startTimer()函數每秒調用它,我不知道如何每次調用時訪問update() 我簡要地研究了protocols但我不確定它們是如何工作的,或者這對我的情況是否有用。

任何幫助將不勝感激!

正如@sschale 建議的那樣,您可以通過使用單例來確保您將在代碼中的任何位置訪問相同的實例。 為此,您需要將 init 設置為 private 並提供一個靜態成員變量來訪問您的單個實例。

class TimerManager 
{
    static let sharedInstance = TimerManager()

    private var timer: NSTimer
    private var timeRemaining: Int

    private init()
    {
        let initialTime = 1
        self.timer = NSTimer()
        self.timeRemaining = initialTime
    }
    private init(initialTime: Int) 
    {
        self.timer = NSTimer()
        self.timeRemaining = initialTime
    }

    ...
}

然后在您的 ViewControllers 中,您可以像這樣調用它:

TimerManager.sharedInstance.startTimer()
class TimerManager {

    private var timer: NSTimer
    private var timeRemaining: Int
    private var intervalBlock: (TimerManager -> ())?

    init(initialTime: Int) {
        self.timer = NSTimer()
        self.timeRemaining = initialTime
    }

    func startTimer(intervalBlock: (TimerManager -> ())? = nil) {
        self.intervalBlock = self
        self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(TimerManager.update), userInfo: nil, repeats: true)
    }

    func endTimer() {
        self.intervalBlock = nil
        self.timer.invalidate()
    }

    func getTimeRemaining() -> Int {
        return self.timeRemaining
    }

    @objc func update() {
        if self.timeRemaining > 0 {
            self.timeRemaining = self.timeRemaining - 1
            intervalBlock()
        }
        else {
            intervalBlock()
            endTimer()
        }
    } 
}

下面是我從這篇文章中發現的后台隊列上 Timer 的最佳實現之一

class RepeatingTimer {

    let timeInterval: TimeInterval

    init(timeInterval: TimeInterval) {
        self.timeInterval = timeInterval
    }

    private lazy var timer: DispatchSourceTimer = {
        let t = DispatchSource.makeTimerSource()
        t.schedule(deadline: .now() + self.timeInterval, repeating: self.timeInterval)
        t.setEventHandler(handler: { [weak self] in
            self?.eventHandler?()
        })
        return t
    }()

    var eventHandler: (() -> Void)?

    private enum State {
        case suspended
        case resumed
    }

    private var state: State = .suspended

    deinit {
        timer.setEventHandler {}
        timer.cancel()
        resume()
        eventHandler = nil
    }

    func resume() {
        if state == .resumed {
            return
        }
        state = .resumed
        timer.resume()
    }

    func suspend() {
        if state == .suspended {
            return
        }
        state = .suspended
        timer.suspend()
    }
}

用法:-

在您的任何 ViewController 中

例如:-

class MyViewController: UIViewController {

// MARK: - Properties
 var timer: RepeatingTimer!

// MARK: - ViewController LifeCycle

override func viewDidLoad() {
        super.viewDidLoad()
     timer =  RepeatingTimer(timeInterval: 1)
        timer.eventHandler = {
            print("Timer called")
        }

}

暫無
暫無

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

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