Post

Replies

Boosts

Views

Activity

Reply to SwiftUI safe area stays offset after keyboard dismissal with “Reduce Motion” + “Prefer Cross-Fade” enabled (iOS 26)
import SwiftUI @main struct ReproApp: App { var body: some Scene { WindowGroup { RootView() } } } struct RootView: View { var body: some View { NavigationStack { ZStack { Color.red.ignoresSafeArea() NavigationLink("Open details") { DetailsView() } .buttonStyle(.borderedProminent) } .safeAreaInset(edge: .bottom, spacing: 0) { Text("Bottom label") .frame(maxWidth: .infinity) .padding(.vertical, 12) .background(.blue) } } } } struct DetailsView: View { @State private var text = "" var body: some View { ZStack(alignment: .top) { Color.green.ignoresSafeArea() TextField("Type here", text: $text) .textFieldStyle(.roundedBorder) .padding() } } }
1w
Reply to SwiftUI safe area stays offset after keyboard dismissal with “Reduce Motion” + “Prefer Cross-Fade” enabled (iOS 26)
Same stale inset here, with a trigger that needs no accessibility settings: a rotation while a plain TextField is focused. Filed as FB24706384 with a 37-line repro project (no third-party code). Steps, starting in portrait: Root screen has .safeAreaInset(edge: .bottom) with a bar. Push a screen with a TextField and focus it (portrait keyboard, 335 pt). Rotate to landscape - the keyboard re-shows at the landscape height (208 pt). Go back while still in landscape. Rotate to portrait. Layout is correct at this point. Background the app, then foreground it. Three things that line up with what you describe: UIWindow.safeAreaInsets.bottom and rootViewController.view.safeAreaInsets.bottom stay correct the whole time (34 portrait, 20 landscape). Only SwiftUI's view-level inset is wrong. The keyboard was hidden with a well-formed notification at 14.68, and the value SwiftUI later installs is that notification's height - in the orientation that is no longer current. The bad value is installed on didEnterBackground, not on foreground. Two workarounds that measured clean here, since the thread has none: Remove .keyboard from UIHostingController.safeAreaRegions whenever no keyboard is presented and restore it on keyboardWillShow. This keeps automatic keyboard avoidance working, and it also fixed a second variant we hit through an SFSafariViewController keyboard. Gate the removal on there being no first responder: when foregrounding back onto an editing screen, keyboardWillShow arrives before sceneDidBecomeActive, so removing it unconditionally breaks avoidance. .ignoresSafeArea(.keyboard, edges: .bottom) - but only applied outside .safeAreaInset. Applied before the inset, on the inset's own content, or on the NavigationStack, the bug remains, which makes the modifier look ineffective. That one cost us a while. Does your case also survive a background/foreground cycle once the safe area is offset? If it does, this looks like one defect with (at least) three entry points - yours, this one, and FB20386257, where an out-of-process WebView keyboard leaves the same inset behind.
1w
Reply to SwiftUI safe area stays offset after keyboard dismissal with “Reduce Motion” + “Prefer Cross-Fade” enabled (iOS 26)
import SwiftUI @main struct ReproApp: App { var body: some Scene { WindowGroup { RootView() } } } struct RootView: View { var body: some View { NavigationStack { ZStack { Color.red.ignoresSafeArea() NavigationLink("Open details") { DetailsView() } .buttonStyle(.borderedProminent) } .safeAreaInset(edge: .bottom, spacing: 0) { Text("Bottom label") .frame(maxWidth: .infinity) .padding(.vertical, 12) .background(.blue) } } } } struct DetailsView: View { @State private var text = "" var body: some View { ZStack(alignment: .top) { Color.green.ignoresSafeArea() TextField("Type here", text: $text) .textFieldStyle(.roundedBorder) .padding() } } }
Replies
Boosts
Views
Activity
1w
Reply to SwiftUI safe area stays offset after keyboard dismissal with “Reduce Motion” + “Prefer Cross-Fade” enabled (iOS 26)
Same stale inset here, with a trigger that needs no accessibility settings: a rotation while a plain TextField is focused. Filed as FB24706384 with a 37-line repro project (no third-party code). Steps, starting in portrait: Root screen has .safeAreaInset(edge: .bottom) with a bar. Push a screen with a TextField and focus it (portrait keyboard, 335 pt). Rotate to landscape - the keyboard re-shows at the landscape height (208 pt). Go back while still in landscape. Rotate to portrait. Layout is correct at this point. Background the app, then foreground it. Three things that line up with what you describe: UIWindow.safeAreaInsets.bottom and rootViewController.view.safeAreaInsets.bottom stay correct the whole time (34 portrait, 20 landscape). Only SwiftUI's view-level inset is wrong. The keyboard was hidden with a well-formed notification at 14.68, and the value SwiftUI later installs is that notification's height - in the orientation that is no longer current. The bad value is installed on didEnterBackground, not on foreground. Two workarounds that measured clean here, since the thread has none: Remove .keyboard from UIHostingController.safeAreaRegions whenever no keyboard is presented and restore it on keyboardWillShow. This keeps automatic keyboard avoidance working, and it also fixed a second variant we hit through an SFSafariViewController keyboard. Gate the removal on there being no first responder: when foregrounding back onto an editing screen, keyboardWillShow arrives before sceneDidBecomeActive, so removing it unconditionally breaks avoidance. .ignoresSafeArea(.keyboard, edges: .bottom) - but only applied outside .safeAreaInset. Applied before the inset, on the inset's own content, or on the NavigationStack, the bug remains, which makes the modifier look ineffective. That one cost us a while. Does your case also survive a background/foreground cycle once the safe area is offset? If it does, this looks like one defect with (at least) three entry points - yours, this one, and FB20386257, where an out-of-process WebView keyboard leaves the same inset behind.
Replies
Boosts
Views
Activity
1w