Here are the steps to reproduce the issue:
iOS 26+ required
create any input that triggers opening keyboard
add toolbar to keyboard (with any buttons)
open keyboard (e.g. by focusing input)
close keyboard
background app (warnings are printed on this step)
get back to foreground
see that bottom safe area is broken (you can add any view that is bound to safe area)
Removing toolbar fixes the issue, btw.
The following warnings are printed:
-[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID. inputModality = Keyboard, inputOperation = dismissAutoFillPanel, customInfoType = UIUserInteractionRemoteInputOperations
-[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID. inputModality = Keyboard, inputOperation = dismissAutoFillPanel, customInfoType = UIUserInteractionRemoteInputOperations
Snapshotting a view (0x15b0a4800, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES.
Here is a test project for demonstrating the issue:
import SwiftUI
struct ContentView: View {
@State var selection: Int = 0
@State var presentingModal = false
var body: some View {
NavigationStack {
VStack(spacing: 0) {
TabView(selection: $selection) {
Group {
Button("Present") { self.presentingModal = true }
.tag(0)
Text("Second").tag(1)
}
.toolbar(.hidden, for: .tabBar)
}
HStack(spacing: 0) {
ForEach(0...1, id: \.self) { tab in
Image(systemName: "cloud.heavyrain.fill")
.padding(.vertical, 16)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
.onTapGesture {
selection = tab
}
}
}
.padding(.horizontal, 16)
.background(Color.secondary)
}
.ignoresSafeArea(.keyboard)
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.inline)
}
.sheet(isPresented: $presentingModal) {
PresentedView()
}
}
}
struct PresentedView: View {
@State var text = ""
@FocusState var isInputActive: Bool
var body: some View {
NavigationStack {
VStack {
TextField("", text: $text)
.focused($isInputActive)
.padding()
.background(.secondary)
Spacer()
}
.padding(.top, 40)
.padding(.horizontal, 20)
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Button("Close") {
isInputActive = false
}
}
}
}
}
}
#Preview {
ContentView()
}
