There are a number of types, propertyWrappers and view modifiers describing "focus" so it is not immediately obvious what they are all for. In this episode we will see how we can control focus for a text field in SwiftUI. We'll see how to use simple Bools as well as your own types to describe which field has focus. Finally we'll touch on a common request that doesn't yet have a great answer: setting focus in onAppear.
Example Form struct LoginForm: View { enum Field: Hashable { case username case password } @State private var username = "" @State private var password = "" var body: some View { Form { TextField("Username", text: $username) SecureField("Password", text: $password) Button("Sign In") { } } } } Using a Boolean to control focus We can start with a simple Bool property to control focus on our username field. @FocusState private var usernameFocused: Bool Note that it does not (and cannot) take an initial value. We use this property wrapper in conjunction with the focused view modifier. TextField("Username", text: $username) .focused($usernameFocused) Now this property wrapper will automatically be set when the field has focus. We can also programmatically focus this field: Button("Sign In") { if username.isEmpty { usernameFocused = true } } Using an Enum value to control focus Using multiple Bool values to control focus on multiple fields is clunky. We can do better. Say we have an enum: enum Field: Hashable { case username case password } We can use this with the @FocusState property wrapper, with one caveat: the value must be optional. @FocusState var focusedField: Field? We then pass a value to the focused() view modifier for each of our fields: TextField("Username", text: $username) .focused($focusedField, equals: .username) SecureField("Password", text: $password) .focused($focusedField, equals: .password) Setting initial focus on appear Now comes the most common request: setting focus to one of these fields when the view is first loaded. Unfortunately as of iOS 15 there is not yet a great solution. We’ll look at one a little later, but for now we have to resort to this: .onAppear { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { focusedField = .username } } References https://onmyway133.com/posts/how-to-focus-textfield-in-swiftui/ https://swiftwithmajid.com/2021/08/24/mastering-focusstate-property-wrapper-in-swiftui/