Try this view modifier.
struct KeyboardManagment: ViewModifier {
@State private var offset: CGFloat = 0
func body(content: Content) -> some View {
GeometryReader { geo in
content
.onAppear {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { (notification) in
guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
withAnimation(Animation.easeOut(duration: 0.5)) {
offset = keyboardFrame.height - geo.safeAreaInsets.bottom
}
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { (notification) in
withAnimation(Animation.easeOut(duration: 0.1)) {
offset = 0
}
}
}
.padding(.bottom, offset)
}
}
}
extension View {
func keyboardManagment() -> some View {
self.modifier(KeyboardManagment())
}
}
Call it at the end of body view. Like this:
struct TestView: View {
var body: some View {
NavigationView {
List {
Text("Hello, World!")
}
}
.keyboardManagment()
}
}
It's not perfect but maybe it works for you.