How do I remove focus from a TextField in SwiftUI on MacOS?

Viewed 866

I have a view in which the user enters data into a several textfields, but I can't allow the user to exit the textfields; one of them is always selected. How do I make the fields un-focus when I click on something else (the background, the submit button, etc.)?

Current View:

struct ContentView: View {
    var body: some View {
        Form {
            TextField("Username", text: $username)
            TextField("Password", text: $password)

            Button("Submit") {
                // Submit data
            }
        }
    }
}
1 Answers

You need to use an optional @FocusState and use .allowsHitTesting(true). On the form, you put a .onTapGesture that sets @FocusState to nil.

struct ContentView: View {
    @State private var username: String = ""
    @State private var password: String = ""
    @FocusState private var focusedField: String?

    var body: some View {
        Form {
            TextField("Username", text: $username)
                .focused($focusedField, equals: "user")
            TextField("Password", text: $password)
                .focused($focusedField, equals: "password")
            Button("Submit") {
                // Submit data
                focusedField = nil
            }
        }
        .onTapGesture {
            focusedField = nil
        }
    }
}

The .allowsHitTesting(true) lets the TextFields accept tap gestures directly, otherwise they would be blocked by the Form's .onTapGesture.

On macOS, in the sidebar, the form is only the size of the Button and TextFields. If you wanted a larger tap area, you would need some kind of background to place it on.

Related