@@ -142,28 +142,47 @@ struct SafeAreaPadded: View {
142142 @State var navBarVisibility = Visibility . visible
143143 @State var tabBarVisibility = Visibility . visible
144144 @State var bottomBarVisibility = Visibility . visible
145-
145+ @AppStorage ( " statusBarHidden " ) var statusBarHidden = false
146+
147+ @State private var animatedSafeAreaInsets : EdgeInsets ? = nil
148+
146149 var body : some View {
147150 GeometryReader { proxy in
148- let _ = print ( " safeAreaInsets: \( proxy. safeAreaInsets) " )
151+ let _ = logger . debug ( " SafeAreaPadded proxy.safeAreaInsets= \( String ( describing : proxy. safeAreaInsets) ) animatedSafeAreaInsets= \( String ( describing : animatedSafeAreaInsets ) ) " )
149152 ScrollView ( . vertical) {
150153 VStack {
154+ Toggle ( " Status bar hidden " , isOn: $statusBarHidden)
151155 SafeAreaVisibilityControl ( name: " Navigation " , visibility: $navBarVisibility)
152156 SafeAreaVisibilityControl ( name: " Tab " , visibility: $tabBarVisibility)
153157 SafeAreaVisibilityControl ( name: " Bottom " , visibility: $bottomBarVisibility)
154158 ForEach ( 0 ..< 40 ) { index in
155159 Text ( " Row: \( index) " )
156160 }
161+ Toggle ( " Status bar hidden " , isOn: $statusBarHidden)
157162 SafeAreaVisibilityControl ( name: " Navigation " , visibility: $navBarVisibility)
158163 SafeAreaVisibilityControl ( name: " Tab " , visibility: $tabBarVisibility)
159164 SafeAreaVisibilityControl ( name: " Bottom " , visibility: $bottomBarVisibility)
160165 }
161166 . frame ( maxWidth: . infinity)
162167 . border ( . blue)
163- . padding ( proxy. safeAreaInsets)
168+ . padding ( animatedSafeAreaInsets ?? proxy. safeAreaInsets)
164169 }
165170 . border ( . red)
166171 . ignoresSafeArea ( )
172+ #if !SKIP
173+ . onChange( of: proxy. safeAreaInsets) { oldValue, newValue in
174+ // In SwiftUI, safe area insets are updated without animation when the bars change, so we need to animate the padding
175+ if animatedSafeAreaInsets == nil {
176+ animatedSafeAreaInsets = newValue
177+ } else if oldValue == newValue {
178+ animatedSafeAreaInsets = newValue
179+ } else {
180+ withAnimation ( . default) {
181+ animatedSafeAreaInsets = newValue
182+ }
183+ }
184+ }
185+ #endif
167186 }
168187 . toolbar {
169188 ToolbarItem ( placement: . bottomBar) {
@@ -173,6 +192,9 @@ struct SafeAreaPadded: View {
173192 . toolbar ( navBarVisibility, for: . navigationBar)
174193 . toolbar ( tabBarVisibility, for: . tabBar)
175194 . toolbar ( bottomBarVisibility, for: . bottomBar)
195+ . animation ( . default, value: navBarVisibility)
196+ . animation ( . default, value: tabBarVisibility)
197+ . animation ( . default, value: bottomBarVisibility)
176198 }
177199}
178200
@@ -221,10 +243,12 @@ struct SafeAreaVisibilityControl: View {
221243 var body : some View {
222244 if visibility == . hidden {
223245 Button ( " Show \( name) Bar " ) {
246+ logger. debug ( " SafeAreaVisibilityControl show \( name) Bar " )
224247 visibility = . visible
225248 }
226249 } else {
227250 Button ( " Hide \( name) Bar " ) {
251+ logger. debug ( " SafeAreaVisibilityControl hide \( name) Bar " )
228252 visibility = . hidden
229253 }
230254 }
0 commit comments