Skip to content

Commit 91b714c

Browse files
authored
Example of animating navigation bar visibility (#97)
1 parent f7331bb commit 91b714c

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

Sources/Showcase/SafeAreaPlayground.swift

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)