TeraTimedCalendarField.swift (1880B)
1 import SwiftUI 2 3 struct TeraTimedCalendarField: View { 4 let label: String 5 let identifier: String 6 let timeZone: TimeZone 7 @Binding var seconds: UInt64? 8 9 var body: some View { 10 if let instant = TeraCalendarEditing.pickerInstant(seconds) { 11 DatePicker(label, selection: Binding( 12 get: { TeraCalendarEditing.pickerInstant(seconds) ?? instant }, 13 set: { 14 if let value = TeraCalendarEditing.pickerSeconds($0), 15 TeraWallTime.from(value, timeZone: timeZone)?.instants(in: timeZone).contains(value) == true 16 { 17 seconds = value 18 } 19 } 20 )) 21 .environment(\.calendar, Calendar(identifier: .gregorian)) 22 .environment(\.timeZone, timeZone) 23 .accessibilityLabel(label) 24 .accessibilityIdentifier(identifier) 25 repeatedTime 26 } else { 27 LabeledContent(label) { 28 Button(seconds == nil ? "Set time" : "Replace unsupported time") { 29 seconds = TeraCalendarEditing.pickerSeconds(Date()) 30 } 31 } 32 .accessibilityIdentifier(identifier) 33 } 34 } 35 36 @ViewBuilder 37 private var repeatedTime: some View { 38 let values = seconds.flatMap { TeraWallTime.from($0, timeZone: timeZone) }?.instants(in: timeZone) ?? [] 39 if values.count == 2 { 40 Picker("\(label), repeated time", selection: $seconds) { 41 ForEach(Array(values.enumerated()), id: \.element) { index, value in 42 Text(occurrence(value, index: index)).tag(Optional(value)) 43 } 44 } 45 .accessibilityIdentifier("\(identifier).occurrence") 46 } 47 } 48 49 private func occurrence(_ seconds: UInt64, index: Int) -> String { 50 guard let instant = TeraCalendarEditing.pickerInstant(seconds) else { return "Time unavailable" } 51 let zone = timeZone.abbreviation(for: instant) ?? timeZone.identifier 52 return "\(index == 0 ? "First" : "Second") occurrence (\(zone))" 53 } 54 }