当 Apple Watch 屏幕变为空白时,它会使应用进入睡眠状态并暂停您已启动的 Timer(s),直到应用重新回到前台。
这在模拟器中不会发生,但会在真实设备上引起问题。
但是,WKInterfaceTimer 不受影响,因为它基于未来日期并在内部处理。
因此,要在应用返回前台后保持计时器同步,只需比较 Timer 块中的两个日期并观察这两个日期之间的差异即可。
在以下示例中,如果您只想更新计时器并知道倒计时何时完成,那么以下内容就足够了:
//Globally declared
@IBOutlet var interfaceTimerCountDown: WKInterfaceTimer!
var countdownToDate: Date?
func startCountdown(from count: TimeInterval) {
//Create a future date to which the countdown will count to
countdownToDate = Date().addingTimeInterval(count)
//Set and Start the WKInterfaceTimer
interfaceTimerCountDown.setDate(countdownToDate!)
interfaceTimerCountDown.start()
//Start your own Timer
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
//Get current date
let currentDate = Date()
//Get difference between future date and current date
let dxTimeInSeconds = self?.countdownToDate!.timeIntervalSince(currentDate) ?? 0
print(dxTimeInSeconds)
//Check if countdown has completed
if dxTimeInSeconds <= 0 {
//...do something
print("Countdown complete!")
timer.invalidate()
}
}
}
但是……
WKInterfaceTimer 和 Timer 将在几毫秒内不同步,因此如果您想在 WKInterfaceTimer 计数更新的同时在更新 UI,那么上面的逻辑是不够的。
就我而言,我想更新图像;就像环形动画一样,我解决它的唯一方法是将WKInterfaceTimer 转储为WKInterfaceLabel + 一个WKInterfaceGroup 并在计时器块中手动更新标签和组的背景图像。
自定义解决方案:
//Declared globally
//for image; to simulate a ring animation image
@IBOutlet var group_lblTimerCount: WKInterfaceGroup!
//Simple label inside a WKInterfaceGroup
@IBOutlet var lblTimerCount: WKInterfaceLabel! //inside group_lblTimerCount
var countdownToDate: Date?
func startCountdown(from count: Int) {
//Create a future date to which the countdown will count to
countdownToDate = Date().addingTimeInterval(TimeInterval(count))
//Update Label and UI
updateTimerLabel(to: count,
from: count)
//Start your own Timer
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
//Get current date
let currentDate = Date()
//Get difference between future date and current date
let dxTimeInSeconds = self?.countdownToDate!.timeIntervalSince(currentDate) ?? 0
//Update Label and UI
let dxTimeInSeconds_Int = Int(round(dxTimeInSeconds))
self?.updateTimerLabel(to: dxTimeInSeconds_Int,
from: count)
//Check if countdown has completed
if dxTimeInSeconds <= 0 {
//...do something
print("Countdown complete!")
//Stop timer
timer.invalidate()
}
}
}
func updateTimerLabel(to count: Int, from total: Int) {
lblTimerCount.setText("\(count)")
updateTimerRing(to: count,
from: total)
}
func updateTimerRing(to count: Int, from total: Int) {
/*
I have 60 images for the ring named from "ring60" to "ring0"
Generated at: http://hmaidasani.github.io/RadialChartImageGenerator
*/
let numberOfImages = 60 //The total number of images you have
let imageIndex = "\(Int(count * numberOfImages/total))"
let imageName = "ring\(imageIndex)"
group_lblTimerCount.setBackgroundImageNamed(imageName)
}
PS:我试图找到一个优雅的解决方案来解决所有这些问题,但找不到一个现成的例子,所以我分享了我最终得到的结果。
希望对某人有所帮助
:)