@@ -29,54 +29,62 @@ struct BolusEntryView: View, HorizontalSizeClassOverride {
2929 @Environment ( \. dismiss) var dismiss
3030
3131 var body : some View {
32- VStack ( spacing: 0 ) {
33- List {
34- historySection
35- summarySection
32+ GeometryReader { geometry in
33+ VStack ( spacing: 0 ) {
34+ List {
35+ self . historySection
36+ self . summarySection
37+ }
38+ // As of iOS 13, we can't programmatically scroll to the Bolus entry text field. This ugly hack scoots the
39+ // list up instead, so the summarySection is visible and the keyboard shows when you tap "Enter Bolus".
40+ // Unfortunately, after entry, the field scoots back down and remains hidden. So this is not a great solution.
41+ // TODO: Fix this in Xcode 12 when we're building for iOS 14.
42+ . padding ( . top, self . shouldAutoScroll ( basedOn: geometry) ? - 200 : - 28 )
43+ . listStyle ( GroupedListStyle ( ) )
44+ . environment ( \. horizontalSizeClass, self . horizontalOverride)
45+
46+ self . actionArea
47+ . frame ( height: self . isKeyboardVisible ? 0 : nil )
48+ . opacity ( self . isKeyboardVisible ? 0 : 1 )
3649 }
37- // As of iOS 13, we can't programmatically scroll to the Bolus entry text field. This ugly hack scoots the
38- // list up instead, so the summarySection is visible and the keyboard shows when you tap "Enter Bolus".
39- // Unfortunately, after entry, the field scoots back down and remains hidden. So this is not a great solution.
40- // TODO: Fix this in Xcode 12 when we're building for iOS 14.
41- . padding ( . top, shouldBolusEntryBecomeFirstResponder ? - 200 : - 28 )
42- . listStyle ( GroupedListStyle ( ) )
43- . environment ( \. horizontalSizeClass, horizontalOverride)
44-
45- actionArea
46- . frame ( height: isKeyboardVisible ? 0 : nil )
47- . opacity ( isKeyboardVisible ? 0 : 1 )
48- }
49- . onKeyboardStateChange { state in
50- self . isKeyboardVisible = state. height > 0
51-
52- if state. height == 0 {
53- // Ensure tapping 'Enter Bolus' can make the text field the first responder again
54- self . shouldBolusEntryBecomeFirstResponder = false
50+ . onKeyboardStateChange { state in
51+ self . isKeyboardVisible = state. height > 0
52+
53+ if state. height == 0 {
54+ // Ensure tapping 'Enter Bolus' can make the text field the first responder again
55+ self . shouldBolusEntryBecomeFirstResponder = false
56+ }
5557 }
56- }
57- . keyboardAware ( )
58- . edgesIgnoringSafeArea ( isKeyboardVisible ? [ ] : . bottom )
59- . navigationBarTitle (
60- viewModel . potentialCarbEntry == nil
61- ? Text ( " Bolus " , comment: " Title for bolus entry screen " )
62- : Text ( " Meal Bolus " , comment : " Title for bolus entry screen when also entering carbs " )
63- )
64- . supportedInterfaceOrientations ( . portrait )
65- . alert ( item : $ viewModel. activeAlert , content : alert ( for : ) )
66- . onReceive ( viewModel . $enteredBolus ) { updatedBolusEntry in
67- // The view model can update the user's entered bolus when the recommendation changes; ensure the text entry updates in tandem.
68- let amount = updatedBolusEntry . doubleValue ( for : . internationalUnit ( ) )
69- self . enteredBolusAmount = amount == 0 ? " " : Self . doseAmountFormatter . string ( from : amount ) ?? String ( amount )
70- }
71- . onReceive ( viewModel . $isManualGlucoseEntryEnabled ) { isManualGlucoseEntryEnabled in
72- // The view model can disable manual glucose entry if CGM data returns.
73- if !isManualGlucoseEntryEnabled {
74- self . isManualGlucoseEntryRowVisible = false
75- self . enteredManualGlucose = " "
58+ . keyboardAware ( )
59+ . edgesIgnoringSafeArea ( self . isKeyboardVisible ? [ ] : . bottom )
60+ . navigationBarTitle (
61+ self . viewModel . potentialCarbEntry == nil
62+ ? Text ( " Bolus " , comment : " Title for bolus entry screen " )
63+ : Text ( " Meal Bolus" , comment: " Title for bolus entry screen when also entering carbs " )
64+ )
65+ . supportedInterfaceOrientations ( . portrait )
66+ . alert ( item : self . $viewModel . activeAlert , content : self . alert ( for : ) )
67+ . onReceive ( self . viewModel. $enteredBolus ) { updatedBolusEntry in
68+ // The view model can update the user's entered bolus when the recommendation changes; ensure the text entry updates in tandem.
69+ let amount = updatedBolusEntry . doubleValue ( for : . internationalUnit ( ) )
70+ self . enteredBolusAmount = amount == 0 ? " " : Self . doseAmountFormatter . string ( from : amount ) ?? String ( amount )
71+ }
72+ . onReceive ( self . viewModel . $isManualGlucoseEntryEnabled ) { isManualGlucoseEntryEnabled in
73+ // The view model can disable manual glucose entry if CGM data returns.
74+ if !isManualGlucoseEntryEnabled {
75+ self . isManualGlucoseEntryRowVisible = false
76+ self . enteredManualGlucose = " "
77+ }
7678 }
7779 }
7880 }
7981
82+ private func shouldAutoScroll( basedOn geometry: GeometryProxy ) -> Bool {
83+ // Taking a guess of 640 to cover iPhone SE, iPod Touch, and other smaller devices.
84+ // Devices such as the iPhone 11 Pro Max do not need to auto-scroll.
85+ shouldBolusEntryBecomeFirstResponder && geometry. size. height < 640
86+ }
87+
8088 private var historySection : some View {
8189 Section {
8290 VStack ( spacing: 8 ) {
0 commit comments