Forms and input
SwiftUI forms: TextField
Learn how to use the TextField control in SwiftUI to get text input, bind it to State, configure the keyboard, handle submit, and manage focus.
8 minute lesson
The first form control we’ll see is the simplest: TextField.
This lets us show some text, like the Text view, and it can be edited by the user, so we can get input in the form of text.
Here’s the most basic example of TextField:
struct ContentView: View {
@State private var name = ""
var body: some View {
Form {
TextField("", text: $name)
}
}
}
The name property is a SwiftUI property wrapped with @State, so the view can update it. The $ prefix passes a binding: the text field writes into name every time the user types a character.
Run the code. You can see an empty text field. You can tap on it:

And you can enter any text inside it:

The first argument of TextField is the placeholder, a string visualized when the field is empty. Use it to tell the user what goes in the field:
TextField("Your name", text: $name)

Styling
Inside a Form, the row styling comes for free. Outside of one, a text field has no visible border, which looks odd. Add one with textFieldStyle():
TextField("Your name", text: $name)
.textFieldStyle(.roundedBorder)
.padding()
Configuring the keyboard
For specific kinds of input you want the right keyboard, and you want iOS to stop “helping”. An email field is the classic case:
TextField("Email", text: $email)
.keyboardType(.emailAddress)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
keyboardType(.emailAddress) puts @ and . on the main keyboard. textInputAutocapitalization(.never) stops iOS from capitalizing the first letter. autocorrectionDisabled() prevents autocorrect from mangling addresses.
Handling submit
When the user presses return, the onSubmit closure runs. You can also change what the return key says with submitLabel():
TextField("Search", text: $query)
.submitLabel(.search)
.onSubmit {
performSearch()
}
Now the return key reads “Search”, and pressing it calls your function.
Passwords
For sensitive input use SecureField. Same API, but the characters show as dots and the text is kept out of screenshots and screen recordings:
SecureField("Password", text: $password)
Controlling focus
Sometimes you want the keyboard to appear as soon as a screen shows up, without waiting for a tap. That’s what @FocusState is for:
struct ContentView: View {
@State private var name = ""
@FocusState private var isFocused: Bool
var body: some View {
Form {
TextField("Your name", text: $name)
.focused($isFocused)
}
.onAppear {
isFocused = true
}
}
}
Setting isFocused to true in code focuses the field and raises the keyboard. Setting it to false dismisses it. Focus becomes just another piece of state.
Lesson completed