BGPicker.swift 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // LoopFollow
  2. // BGPicker.swift
  3. // Created by Jonas Björkert.
  4. import HealthKit
  5. import SwiftUI
  6. /// Lets the user pick a BG-related number (mg/dL or mmol/L) inside any form row.
  7. struct BGPicker: View {
  8. let title: String
  9. let range: ClosedRange<Double>
  10. @Binding var value: Double
  11. // MARK: – Helpers
  12. private var unit: HKUnit { Localizer.getPreferredUnit() }
  13. private var allValues: [Double] {
  14. if unit == .millimolesPerLiter {
  15. let step = 0.1
  16. let lower = ceil((range.lowerBound / 18) / step) * step
  17. let upper = floor((range.upperBound / 18) / step) * step
  18. return stride(from: lower, through: upper, by: step).map { $0 * 18 }
  19. } else {
  20. return Array(stride(from: range.lowerBound,
  21. through: range.upperBound,
  22. by: 1))
  23. }
  24. }
  25. private var snappedValue: Binding<Double> {
  26. Binding(
  27. get: { allValues.min(by: { abs($0 - value) < abs($1 - value) }) ?? value },
  28. set: { value = $0 }
  29. )
  30. }
  31. var body: some View {
  32. Picker(selection: snappedValue) {
  33. ForEach(allValues, id: \.self) { v in
  34. Text("\(Localizer.formatQuantity(v)) \(unit.localizedShortUnitString)")
  35. .tag(v)
  36. }
  37. } label: {
  38. Text(title)
  39. }
  40. }
  41. }