2

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?

mars
  • 109
  • 5
  • 21
  • 1
    You can't update the icon dynamically. Only apple can do that. You should be able to create a widget and send a large set of timeline entries that change every second. – Paulw11 Feb 18 '21 at 11:20

5 Answers5

4

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

enter image description here

Duke Fredrick
  • 163
  • 10
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:

pawello2222
  • 46,897
  • 22
  • 145
  • 209
0

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)")
lorem ipsum
  • 21,175
  • 5
  • 24
  • 48
  • Thanks for your reply. But I want to show clock animation that second hand keeps moving every second. Any way to implemente it? – mars Feb 18 '21 at 15:51
0

The idea is to simply spam WidgetCenter.shared.reloadAllTimelines() every tick. Check this repo: https://github.com/lexrus/LexClockWidget

Den Andreychuk
  • 420
  • 4
  • 14
  • I tried this project, It is not work any more – mars Jun 09 '21 at 10:57
  • There is a limit to how many times you can reload the timeline. This is really brute force and eventually won't update anymore until the next day. – TruMan1 Mar 27 '22 at 14:34
0

Xcode 14 Update You can add _clockHandRotationEffect to a swift package with xcode13, and use it in Xcode14. This is an exampleClockRotationEffect

Eilgnaw
  • 121
  • 5