はじめに
ログイン画面でIDやパスワードが未入力だった場合に対象の入力欄にフォーカスを当てたいと思い調べてみました。
環境
Xcode15.2
iOS15 ~
内容
@FocusState
はiOS15から使えるものです。
このような簡単なログイン画面でボタンを押した際にバリデーションに引っかかれば対象のテキストフィールドにフォーカスを当てる実装ができます。
当然、バリデーションに引っかかった場合は何が問題なのかフィードバックしてあげる必要もありますが、今回はスキップします。

struct LoginView: View {
+ enum Field: Hashable {
+ case usernameField
+ case passwordField
+ }
@State private var username = ""
@State private var password = ""
+ @FocusState private var focusedField: Field?
var body: some View {
VStack(spacing: 20) {
TextField("Username", text: $username)
.autocapitalization(.none)
.disableAutocorrection(true)
.padding(8)
.border(Color.gray)
+ .focused($focusedField, equals: .usernameField)
SecureField("Password", text: $password)
.padding(8)
.border(Color.gray)
+ .focused($focusedField, equals: .passwordField)
Button("Sign In") {
if username.isEmpty {
+ focusedField = .usernameField
} else if password.isEmpty {
+ focusedField = .passwordField
} else {
// handleLogin(username, password)
}
}
.buttonStyle(.bordered)
.padding(20)
}
.padding(30)
}
}
複数のViewに対して.focused
で同じenumの値を入れたり、同じViewに対して複数の.focused
を使わない限りこの実装で問題なくやりたいことはできます。
ボタンを押したタイミングで上記の実装では空文字かどうかを調べていますが、独自のバリデーションをかけるのが良さそうです。
おわりに
これまで@FocusState
でBoolを使う実装はしておりましたが、enumを使う方法は知らなかったので実装もスッキリするしどんどん使っていこうと思います。