Reputation: 411
I know this has been posted before, but I'm new to swift and i would like to find help as per my situation. So i need to run a timer, and when the stopMusic() is called(somewhere in my app), i need to pause the timer, then when the playMusic() is called, i need to resume the timer.
Here is what i have:
override func viewDidLoad() {
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(38.2, target: self, selector: "runAnimation", userInfo: nil, repeats: false)
}
func stopMusic() {
//Pause Timer
}
func playMusic() {
//Resume Timer
}
Thank you for any help you can provide!!!
Upvotes: 2
Views: 7169
Reputation: 4555
Swift 5.
Resumable timer:
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()
}
}
}
Usage:
private var playTimer: ResumableTimer?
playTimer = ResumableTimer(interval: 5.0) { [weak self] in
self?.doSomethingOnTimerFire()
}
playTimer?.start()
Upvotes: 7
Reputation: 131398
Short answer: You can't. Timers can't be paused.
Instead you need to record the current time when you start the timer:
let startTime = NSDate.timeIntervalSinceReferenceDate()
let interval = 38.2
//Start your timer
runFirstDropTimer = NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: "runAnimation",
userInfo: nil,
repeats: false)
Then, when you want to pause your timer, invalidate it and figure out how much time is left:
runFirstDropTimer.invalidate()
let elapsed = NSDate.timeIntervalSinceReferenceDate() - startTime
let remaining = interval - elapsed
And finally when you want to resume your timer create a new timer with the remaining
value.
Upvotes: 6