banner: float below nav bar (no glass pass-through) + slide-up dismiss

Position the floating banner just below the nav bar so it no longer overlays the iOS 26 Liquid Glass back/toolbar chrome behind it — tapping retry can no longer also select the control beneath. Banner now slides up + fades on dismiss/timeout (one style for all notifications); full-rect contentShape for a solid tap target.
This commit is contained in:
FuelBoard Contributor
2026-08-19 08:43:35 +01:00
parent ba83f9e1c0
commit 8936643e0e
+17 -8
View File
@@ -482,14 +482,22 @@ struct ContentView: View {
} }
private var mainContent: some View { private var mainContent: some View {
ZStack(alignment: .top) { GeometryReader { geo in
rootTabView ZStack(alignment: .top) {
if let banner = activeBanner { rootTabView
// Floating above the tabs: overlays content, never pushes it. if let banner = activeBanner {
floatingBanner(banner) // Floating just below the nav bar: overlays content (never
.padding(.top, 6) // pushes it) and stays clear of the iOS 26 nav/toolbar
.transition(.asymmetric(insertion: .move(edge: .top).combined(with: .opacity), // Liquid Glass chrome so a tap on the banner can't also
removal: .opacity)) // trigger the control behind it.
floatingBanner(banner)
.padding(.top, geo.safeAreaInsets.top + 52)
.transition(.asymmetric(
insertion: .move(edge: .top).combined(with: .opacity),
// Slide up + fade on dismiss/timeout (one style for all).
removal: .move(edge: .top).combined(with: .opacity)
))
}
} }
} }
.animation(.spring(response: 0.3, dampingFraction: 0.8), value: activeBanner) .animation(.spring(response: 0.3, dampingFraction: 0.8), value: activeBanner)
@@ -600,6 +608,7 @@ struct ContentView: View {
) )
.padding(.horizontal, 12) .padding(.horizontal, 12)
} }
.contentShape(Rectangle())
.buttonStyle(.plain) .buttonStyle(.plain)
.accessibilityLabel(accessibilityLabel) .accessibilityLabel(accessibilityLabel)
} }