BolusView.swift 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import SwiftUI
  2. struct BolusView: View {
  3. @EnvironmentObject var state: WatchStateModel
  4. @State var steps = 0.0
  5. var numberFormatter: NumberFormatter {
  6. let formatter = NumberFormatter()
  7. formatter.numberStyle = .decimal
  8. formatter.minimum = 0
  9. formatter.maximum = Double((state.maxBolus ?? 5) / (state.bolusIncrement ?? 0.1)) as NSNumber
  10. formatter.maximumFractionDigits = (state.bolusIncrement ?? 0.1) > 0.05 ? 1 : 2
  11. formatter.minimumFractionDigits = (state.bolusIncrement ?? 0.1) > 0.05 ? 1 : 2
  12. formatter.allowsFloats = true
  13. formatter.roundingIncrement = Double(state.bolusIncrement ?? 0.1) as NSNumber
  14. return formatter
  15. }
  16. var body: some View {
  17. GeometryReader { geo in
  18. VStack(spacing: 16) {
  19. HStack {
  20. Button {
  21. let newValue = steps - 1
  22. steps = max(newValue, 0)
  23. } label: { Image(systemName: "minus") }
  24. .frame(width: geo.size.width / 4)
  25. Spacer()
  26. Text(numberFormatter.string(from: (steps * Double(state.bolusIncrement ?? 0.1)) as NSNumber)! + " U")
  27. .font(.headline)
  28. .focusable(true)
  29. .digitalCrownRotation(
  30. $steps,
  31. from: 0,
  32. through: Double((state.maxBolus ?? 5) / (state.bolusIncrement ?? 0.1)),
  33. by: 1,
  34. sensitivity: .medium,
  35. isContinuous: false,
  36. isHapticFeedbackEnabled: true
  37. )
  38. Spacer()
  39. Button {
  40. let newValue = steps + 1
  41. steps = min(newValue, Double((state.maxBolus ?? 5) / (state.bolusIncrement ?? 0.1)))
  42. } label: { Image(systemName: "plus") }
  43. .frame(width: geo.size.width / 4)
  44. }
  45. HStack {
  46. Button {
  47. state.isBolusViewActive = false
  48. }
  49. label: {
  50. Image(systemName: "xmark.circle.fill")
  51. .resizable()
  52. .foregroundColor(.loopRed)
  53. .frame(width: 30, height: 30)
  54. }
  55. Button {
  56. enactBolus()
  57. }
  58. label: {
  59. Image(systemName: "checkmark.circle.fill")
  60. .resizable()
  61. .foregroundColor(.loopGreen)
  62. .frame(width: 30, height: 30)
  63. }
  64. .disabled(steps <= 0)
  65. }
  66. }.frame(maxHeight: .infinity)
  67. }
  68. .navigationTitle("Enact Bolus")
  69. .onAppear {
  70. steps = Double((state.bolusRecommended ?? 0) / (state.bolusIncrement ?? 0.1))
  71. }
  72. }
  73. private func enactBolus() {
  74. let amount = steps * Double(state.bolusIncrement ?? 0.1)
  75. state.enactBolus(amount: amount)
  76. }
  77. }
  78. struct BolusView_Previews: PreviewProvider {
  79. static var previews: some View {
  80. let state = WatchStateModel()
  81. state.bolusRecommended = 10.3
  82. state.bolusIncrement = 0.05
  83. return Group {
  84. BolusView()
  85. BolusView().previewDevice("Apple Watch Series 5 - 40mm")
  86. BolusView().previewDevice("Apple Watch Series 3 - 38mm")
  87. }.environmentObject(state)
  88. }
  89. }