How to Display Current Time (Realtime) in iOS 14 Home Widget

Updating time text label each minute in WidgetKit

A possible solution is to use the time date style:

/// A style displaying only the time component for a date.
///
/// Text(event.startDate, style: .time)
///
/// Example output:
/// 11:23PM
public static let time: Text.DateStyle


  1. You need a simple Entry with a Date property:
struct SimpleEntry: TimelineEntry {
let date: Date
}

  1. Create an Entry every minute until the next midnight:
struct SimpleProvider: TimelineProvider {
...

func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
var entries = [SimpleEntry]()
let currentDate = Date()
let midnight = Calendar.current.startOfDay(for: currentDate)
let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!

for offset in 0 ..< 60 * 24 {
let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: midnight)!
entries.append(SimpleEntry(date: entryDate))
}

let timeline = Timeline(entries: entries, policy: .after(nextMidnight))
completion(timeline)
}
}

  1. Display the date using the time style:
struct SimpleWidgetEntryView: View {
var entry: SimpleProvider.Entry

var body: some View {
Text(entry.date, style: .time)
}
}

If you want to customise the date format you can use your own DateFormatter:

struct SimpleWidgetEntryView: View {
var entry: SimpleProvider.Entry

static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "HH:mm"
return formatter
}()

var body: some View {
Text("\(entry.date, formatter: Self.dateFormatter)")
}
}

Here is a GitHub repository with different Widget examples including the Clock Widget.

iOS clock animations on homescreen widget

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

Sample Image

iOS Widget does not read UserDeafults value for the first time in the home screen

.sink won't work in a widget.

Whatever you want to display in a widget has to be done when you setup the timeline. Widgets aren't listening for changes.

You have to reload the widget timelines from the app when there are changes. consider each timeline entry like a screenshot.

WidgetCenter.shared.reloadAllTimelines()

Reloading is metered so make sure you have a check and don't reload excessively.



Related Topics



Leave a reply



Submit