TimePicker.swift 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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. .pickerStyle(.wheel)
  41. .labelsHidden()
  42. }
  43. private func text(for time: TimeInterval) -> Text {
  44. let dayAtTime = fixedMidnight.addingTimeInterval(time)
  45. return Text("\(dayAtTime, formatter: Self.dateFormatter)")
  46. .foregroundColor(.primary)
  47. }
  48. }