@FocusState provides a way to handle the focus state on textfields related to each other.

1. Enum

The first step is to create an enum with a case for each one the textfields. Let’s work on this example with a view that register a user.

2. Property to store the focus state

The view that contains the textfields needs a optional property to store the status. This property’s value represents the textfield that is on focus. If the property is set as nil none of them will be on focus. The most important thing is to wrap the property with @FocusState property wrapper.

enum SignUpFieldFocus { // 1. Enum 
    case name, email, password
}

struct SignUpView: View {
    @State var name = ""
    @State var email = ""
    @State var password = ""
    @FocusState var focusTextField: SignUpFieldFocus? // 2. Property to stores the focus state
    
    var body: some View {
        VStack {
            TextField("Name", text: $name)
                .focused($focusTextField, equals: .name) // 3. Set the case 
            TextField("Email", text: $email)
                .focused($focusTextField, equals: .email)
            TextField("Password", text: $password)
                .focused($focusTextField, equals: .password)
        }       
        .onSubmit {
            switch focusTextField { // 4. Update the focus state
            case .name:
                focusTextField = .email
            case .email:
                focusTextField = .password
            case .password:
                focusTextField = nil
            case .none:
                break
            }
        }
    }
}

3. Set the case

The focused modifier has to be added to each one of the textfields. The modifier takes two arguments. First one the binding property that stores the focus state. Second one the value that represents the actual textifield.

func focused<Value>(_ binding: FocusState<Value>.Binding, equals value: Value) -> some View where Value : Hashable

4. Update the focus state

The focusTextField property can be updated in different ways. In this example is updated when the user submits with the keyboard. So after pressing enter it changes focus to the next textfield. When the user submits the password none of them will be on focus.