How to hide keyboard when using SwiftUI?

Hitesh Surani picture Hitesh Surani · Jun 7, 2019 · Viewed 32.1k times · Source

How to hide keyboard using SwiftUI for below cases?

Case 1

I have TextField and I need to hide the keyboard when the user clicks the return button.

Case 2

I have TextField and I need to hide the keyboard when the user taps outside.

How I can do this using SwiftUI?

Note:

I have not asked a question regarding UITextField. I want to do it by using SwifUI.TextField.

Answer

rraphael picture rraphael · Jun 7, 2019

You can force the first responder to resign by sending an action to the shared application:

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

Now you can use this method to close the keyboard whenever you desire:

struct ContentView : View {
    @State private var name: String = ""

    var body: some View {
        VStack {
            Text("Hello \(name)")
            TextField("Name...", text: self.$name) {
                // Called when the user tap the return button
                // see `onCommit` on TextField initializer.
                UIApplication.shared.endEditing()
            }
        }
    }
}

If you want to close the keyboard with a tap out, you can create a full screen white view with a tap action, that will trigger the endEditing(_:):

struct Background<Content: View>: View {
    private var content: Content

    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }

    var body: some View {
        Color.white
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        .overlay(content)
    }
}

struct ContentView : View {
    @State private var name: String = ""

    var body: some View {
        Background {
            VStack {
                Text("Hello \(self.name)")
                TextField("Name...", text: self.$name) {
                    self.endEditing()
                }
            }
        }.onTapGesture {
            self.endEditing()
        }
    }

    private func endEditing() {
        UIApplication.shared.endEditing()
    }
}