'iOS clock animations on homescreen widget
I want to add a homescreen widget to my app, just like the iOS system Clock app, the second hand keeps moving every second. I have been searching on Google and Github for a long time and have not found a suitable solution. I have seen that there are already third-party apps that can implement such desktop widgets. For example:
How do they do it?
Solution 1:[1]
According to Apple it can't be done.
Here you can find a comment made by a Systems Engineer from Apple:
[...] However, you cannot update views to the time other than the relative date text label. So you cannot replicate the Clock widget for example and have second hands on a clock tick by while the widget is visible. Sorry.
Also, from the Human Interface Guidelines for Widgets:
Keep your widget up-to-date. To remain relevant and useful, widgets should periodically refresh their information. Widgets don’t support continuous, real-time updates, and the system may adjust the limits for updates depending on various factors.
My understanding is that the only way for third-party apps to provide such animations is to use private API. The system Clock Widget does this after all, so it might actually be possible to replicate this behaviour using some private methods that I'm not aware of.
If you're interested in exploring some more shady corners of SwiftUI, this post might get you started:
Solution 2:[2]
Apple has a whole page on how to display dynamic Dates.
The WWDC20 widgets code-along example updates by the second. Their timeline entires are every minute.
Using a Text view in your widget, you can display dates and times that stay up to date onscreen. The following examples show the combinations available. To display a relative time that updates automatically:
let components = DateComponents(minute: 11, second: 14)
let futureDate = Calendar.current.date(byAdding: components, to: Date())!
Text(futureDate, style: .relative)
// Displays:
// 11 min, 14 sec
Text(futureDate, style: .offset)
// Displays:
// -11 minutes
For dates in the future, the timer style counts down until the current time reaches the specified date and time, and counts up when the date passes. To display an absolute date or time:
// Absolute Date or Time
let components = DateComponents(year: 2020, month: 4, day: 1, hour: 9, minute: 41)
let aprilFirstDate = Calendar.current(components)!
Text(aprilFirstDate, style: .date)
Text("Date: \(aprilFirstDate, style: .date)")
Text("Time: \(aprilFirstDate, style: .time)")
Solution 3:[3]
The idea is to simply spam WidgetCenter.shared.reloadAllTimelines() every tick. Check this repo: https://github.com/lexrus/LexClockWidget
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | pawello2222 |
| Solution 2 | lorem ipsum |
| Solution 3 | Den Andreychuk |
