TimePicker.swift 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //
  2. // TimePicker.swift
  3. // LoopKitUI
  4. //
  5. // Created by Michael Pangburn on 4/23/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. /// Binds a `TimeInterval` describing an offset from midnight to a selected picker value.
  10. ///
  11. /// For example, a value of `0` corresponds to midnight, while a value of `7200` corresponds to 2:00 AM.
  12. ///
  13. /// The offset is not relative to the current date. Use `TimePicker` for selecting the time of a recurring daily event, _not_ for selecting the time at which an alarm should sound later this afternoon.
  14. public struct TimePicker: View {
  15. @Binding private var offsetFromMidnight: TimeInterval
  16. private let allValues: [TimeInterval]
  17. private let fixedMidnight = Calendar.current.startOfDay(for: Date(timeIntervalSinceReferenceDate: 0))
  18. private static let dateFormatter: DateFormatter = {
  19. let dateFormatter = DateFormatter()
  20. dateFormatter.dateStyle = .none
  21. dateFormatter.timeStyle = .short
  22. return dateFormatter
  23. }()
  24. public init(
  25. offsetFromMidnight: Binding<TimeInterval>,
  26. bounds: ClosedRange<TimeInterval>,
  27. stride: TimeInterval,
  28. isTimeExcluded: (TimeInterval) -> Bool = { _ in false }
  29. ) {
  30. self._offsetFromMidnight = offsetFromMidnight
  31. self.allValues = Swift.stride(from: bounds.lowerBound, through: bounds.upperBound, by: stride)
  32. .filter { !isTimeExcluded($0) }
  33. }
  34. public var body: some View {
  35. Picker(selection: $offsetFromMidnight, label: Text(LocalizedString("Time", comment: "Label for offset from midnight picker"))) {
  36. ForEach(allValues, id: \.self) { time in
  37. self.text(for: time)
  38. }
  39. }
  40. .labelsHidden()
  41. }
  42. private func text(for time: TimeInterval) -> Text {
  43. let dayAtTime = fixedMidnight.addingTimeInterval(time)
  44. return Text("\(dayAtTime, formatter: Self.dateFormatter)")
  45. .foregroundColor(.primary)
  46. }
  47. }