TextField in SwiftUI and Keyboard Management

In my traditional Swift/UIKit applications, I use IQKeyboardManager to make sure that the on-screen keyboard does not obscure the text field (or text view) being edited.


What is the situation in SwiftUI? Is this something that is part of the "it just works" part of the framework, or do I still have to implement it? And if the latter, any thoughts as to how to approach the problem?


Thanks,

Rick Aurbach

Replies

You should move your threads to SwiftUI section of the forum. You'll get more focused answers there.

You should have a lookk at this. Seems to be a fairly simple solution to implement.


https://stackoverflow.com/questions/56491881/move-textfield-up-when-thekeyboard-has-appeared-by-using-swiftui-ios

Link to Stackoverflow provided by @Claude31 is not even accepted, nor helps points to any acceptable solution.
Please fill a feedback so Apple becomes more aware of that. So many people are asking for e.g. 'becomeFirstResponder' (https://developer.apple.com/forums/thread/650263) but I would also like to see things like (part of my feedback):
  • It would be great to be able to set the first responder manually in SwiftUI (e.g. focus TextField or dismiss the keyboard).

  • It would be great to be able to add a toolbar above the keyboard (add custom buttons like a ready or next button)

  • It would be great to be able to automatically shrink the visible view when the keyboard comes in to view. Like a VStack with the view and the keyboard.

So please fill a feedback. I would love to become a native solution.

Try this view modifier.
Code Block
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:
Code Block
struct TestView: View {
    var body: some View {
        NavigationView {
            List {
                Text("Hello, World!")
            }
        }
        .keyboardManagment()
    }
}

It's not perfect but maybe it works for you.
  • In some situations this is causing me === AttributeGraph: cycle detected through attribute ===

Add a Comment
Take a look at .ignoresSafeArea(...), which is new in Xcode 12 beta 4. The first parameter allows you to specify whether or not to include the keyboard in the safe area. Being able to treat the keyboard like a safe area seems to be a good route to go. I find the documentation to be a little confusing, but in my use case, .ignoresSafeArea(.container) allows my view hierarchy to avoid the keyboard. I’m not including keyboard in that first parameter, meaning the keyboard IS considered a safe area and hence my layout avoids it.
  • This actually helped me to fix an issue where I did NOT want my keyboard to move the views. .ignoresSafeArea(.keyboard) and it did not affect the layout. Without that line, on my view, a button would move up so it stays visible when the keyboard appears, which we did not want to happen.

Add a Comment