App/Widgets/ActivityLayout.swift
36 lines · 1146 bytes
1import SwiftUI
2import WidgetKit
3
4/// `full` in a normal Dynamic Island, `limited` where it is narrow: landscape, iPhone Duo, or several
5/// activities at once (iOS 27).
6struct IslandWidth<Full: View, Limited: View>: View {
7 @ViewBuilder var full: Full
8 @ViewBuilder var limited: Limited
9
10 var body: some View {
11 if #available(iOS 27, *) {
12 LimitedWidthReader(full: full, limited: limited)
13 } else {
14 full
15 }
16 }
17}
18
19@available(iOS 27, *)
20private struct LimitedWidthReader<Full: View, Limited: View>: View {
21 @Environment(\.isDynamicIslandLimitedInWidth) private var isLimited
22 var full: Full
23 var limited: Limited
24
25 var body: some View {
26 if isLimited { limited } else { full }
27 }
28}
29
30/// Counts down to `date`, or up from it once passed. Unlike `Text(timerInterval:)` it takes the width of its
31/// digits, not the widest the timer could get.
32func liveTimer(_ date: Date) -> Text {
33 date > .now
34 ? Text(.currentDate, format: .timer(countingDownIn: Date.now..<date))
35 : Text(.currentDate, format: .stopwatch(startingAt: date, maxPrecision: .seconds(1)))
36}