iOS 主屏幕小部件上的时钟动画

iOS clock animations on homescreen widget

我想在我的应用程序中添加一个主屏幕小部件,就像 iOS 系统时钟应用程序一样,秒针每秒都在走动。我在Google 和Github 上找了很久都没有找到合适的解决方案。我看到已经有第三方应用程序可以实现这样的桌面小部件。例如:

他们是怎么做到的?

Apple 在如何显示动态 Date 方面有完整的 page

WWDC20 widgets code-along 示例每秒更新一次。他们的时间线全是每一分钟。

使用小部件中的文本视图,您可以在屏幕上显示最新的日期和时间。以下示例显示了可用的组合。 要显示自动更新的相对时间:

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

对于未来的日期,计时器样式会倒计时,直到当前时间到达指定的日期和时间,并在日期过去时开始计时。 要显示绝对日期或时间:

// 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)")

根据 Apple 的说法,这是不可能的。

Here 你可以找到 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.

此外,来自 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.

我的理解是,第三方应用提供此类动画的唯一方法是使用私有 API。毕竟系统 Clock Widget 会执行此操作,因此实际上可以使用一些我不知道的私有方法来复制此行为。

如果您有兴趣探索 SwiftUI 的一些更阴暗的角落,这个 post 可能会让您入门:

我们的想法是简单地在每次更新时 WidgetCenter.shared.reloadAllTimelines() 发送垃圾邮件。检查此回购协议:https://github.com/lexrus/LexClockWidget

使用View._clockHandRotationEffect(.secondHand, in: .current, anchor: .center)