Swift : 暂停和恢复 NSTimer
Swift : Pause and Resume NSTimer
我知道之前已经发布过,但我是 swift 的新手,我想根据我的情况寻求帮助。
所以我需要 运行 一个计时器,当调用 stopMusic() 时(在我的应用程序中的某个地方),我需要暂停计时器,然后当调用 playMusic() 时,我需要恢复计时器。
这是我所拥有的:
override func viewDidLoad() {
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(38.2, target: self, selector: "runAnimation", userInfo: nil, repeats: false)
}
func stopMusic() {
//Pause Timer
}
func playMusic() {
//Resume Timer
}
感谢您提供的任何帮助!!!
简答:你不能。计时器无法暂停。
相反,您需要在启动计时器时记录当前时间:
let startTime = NSDate.timeIntervalSinceReferenceDate()
let interval = 38.2
//Start your timer
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: "runAnimation",
userInfo: nil,
repeats: false)
然后,当你想暂停你的计时器时,使它无效并计算还剩多少时间:
runFirstDropTimer.invalidate()
let elapsed = NSDate.timeIntervalSinceReferenceDate() - startTime
let remaining = interval - elapsed
最后,当您想恢复计时器时,创建一个具有 remaining
值的新计时器。
Swift 5.
可恢复计时器:
class ResumableTimer: NSObject {
private var timer: Timer? = Timer()
private var callback: () -> Void
private var startTime: TimeInterval?
private var elapsedTime: TimeInterval?
// MARK: Init
init(interval: Double, callback: @escaping () -> Void) {
self.callback = callback
self.interval = interval
}
// MARK: API
var isRepeatable: Bool = false
var interval: Double = 0.0
func isPaused() -> Bool {
guard let timer = timer else { return false }
return !timer.isValid
}
func start() {
runTimer(interval: interval)
}
func pause() {
elapsedTime = Date.timeIntervalSinceReferenceDate - (startTime ?? 0.0)
timer?.invalidate()
}
func resume() {
interval -= elapsedTime ?? 0.0
runTimer(interval: interval)
}
func invalidate() {
timer?.invalidate()
}
func reset() {
startTime = Date.timeIntervalSinceReferenceDate
runTimer(interval: interval)
}
// MARK: Private
private func runTimer(interval: Double) {
startTime = Date.timeIntervalSinceReferenceDate
timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: isRepeatable) { [weak self] _ in
self?.callback()
}
}
}
用法:
private var playTimer: ResumableTimer?
playTimer = ResumableTimer(interval: 5.0) { [weak self] in
self?.doSomethingOnTimerFire()
}
playTimer?.start()
我知道之前已经发布过,但我是 swift 的新手,我想根据我的情况寻求帮助。 所以我需要 运行 一个计时器,当调用 stopMusic() 时(在我的应用程序中的某个地方),我需要暂停计时器,然后当调用 playMusic() 时,我需要恢复计时器。
这是我所拥有的:
override func viewDidLoad() {
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(38.2, target: self, selector: "runAnimation", userInfo: nil, repeats: false)
}
func stopMusic() {
//Pause Timer
}
func playMusic() {
//Resume Timer
}
感谢您提供的任何帮助!!!
简答:你不能。计时器无法暂停。
相反,您需要在启动计时器时记录当前时间:
let startTime = NSDate.timeIntervalSinceReferenceDate()
let interval = 38.2
//Start your timer
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: "runAnimation",
userInfo: nil,
repeats: false)
然后,当你想暂停你的计时器时,使它无效并计算还剩多少时间:
runFirstDropTimer.invalidate()
let elapsed = NSDate.timeIntervalSinceReferenceDate() - startTime
let remaining = interval - elapsed
最后,当您想恢复计时器时,创建一个具有 remaining
值的新计时器。
Swift 5.
可恢复计时器:
class ResumableTimer: NSObject {
private var timer: Timer? = Timer()
private var callback: () -> Void
private var startTime: TimeInterval?
private var elapsedTime: TimeInterval?
// MARK: Init
init(interval: Double, callback: @escaping () -> Void) {
self.callback = callback
self.interval = interval
}
// MARK: API
var isRepeatable: Bool = false
var interval: Double = 0.0
func isPaused() -> Bool {
guard let timer = timer else { return false }
return !timer.isValid
}
func start() {
runTimer(interval: interval)
}
func pause() {
elapsedTime = Date.timeIntervalSinceReferenceDate - (startTime ?? 0.0)
timer?.invalidate()
}
func resume() {
interval -= elapsedTime ?? 0.0
runTimer(interval: interval)
}
func invalidate() {
timer?.invalidate()
}
func reset() {
startTime = Date.timeIntervalSinceReferenceDate
runTimer(interval: interval)
}
// MARK: Private
private func runTimer(interval: Double) {
startTime = Date.timeIntervalSinceReferenceDate
timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: isRepeatable) { [weak self] _ in
self?.callback()
}
}
}
用法:
private var playTimer: ResumableTimer?
playTimer = ResumableTimer(interval: 5.0) { [weak self] in
self?.doSomethingOnTimerFire()
}
playTimer?.start()