DroppyCompactClock
A clock for compact live-activity content that the host drives (DroppyKit 1.23.0).
@MainActor struct DroppyCompactClock<Content> where Content : View
Available from DroppyKit 1.23.0.
Droppy's own compact rows (the meeting timer, the calendar ring, the recording waveform) never run a timer of their own. Each draws from a timeline that ticks only while the row is up and at rest, and holds still while the host reveals it, takes it away, moves the notch for a shelf spring or conceals the notch. This is that timeline, for a droplet:
public func makeCompactTrailing(context: CompactLiveActivityContext) -> AnyView {
AnyView(
DroppyCompactClock { now in
Text(timer.remaining(at: now))
.font(.system(size: DroppyLiveActivityMetrics.labelFontSize, weight: .medium))
.monospacedDigit()
}
)
}Use it instead of a Timer, a Timer.publish sink, a repeatForever animation or a TimelineView(.animation) in a compact view. Those keep running while nobody can see the row, and the host cannot stop them; this one stops on pausesLiveContent, which the host sets through EnvironmentValues.dropletCompactPresentation.
- Ticks land on whole multiples of
interval(whole seconds by default), so a clock flips its digit when the wall clock does, never up to a second late. - While paused,
contentkeeps the date of the last tick. - The shortest interval is
compactClockMinimumInterval(30 a second), and Reduce Motion holds anything faster than a second to one tick a second. - Outside a compact mount (a settings preview, the harness) nothing pauses it, so it simply ticks.
Initializers
init(every:content:)
@MainActor init(every interval: TimeInterval = 1, @ViewBuilder content: @escaping (Date) -> Content)
Creates a clock that ticks every interval seconds while the compact surface it is in is up and at rest.
Properties
body
@MainActor var body: some View { get }