
SwiftUIでテキストフィールドのフォーカス状態(入力中かどうか)を制御したいときに便利なのが @FocusState
です。
ユーザーがどのフィールドに入力しているかを把握したり、特定のタイミングでキーボードを表示・非表示にしたりする際に欠かせないプロパティラッパーです。
この記事では @FocusState
の基本的な意味や使い方、活用シーン、注意点までをわかりやすく丁寧に解説します。
@FocusState とは?
@FocusState
は、SwiftUIのビューにおける「フォーカス状態(=入力対象)」を管理するためのプロパティラッパーです。
テキストフィールドや検索バーなどで、現在どのフィールドにフォーカスがあるか(ユーザーが入力しているか)を状態として持ち、Viewの状態と連動させることができます。
UIKitでは becomeFirstResponder()
や resignFirstResponder()
を使ってフォーカス制御していましたが、SwiftUIでは @FocusState
を使えばより宣言的に書けます。
具体例①:テキストフィールドのフォーカスを管理する基本の使い方
まずは1つのテキストフィールドのフォーカスを制御するシンプルな例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct ContentView: View { @State private var name = "" @FocusState private var isFocused: Bool var body: some View { VStack { TextField("名前を入力", text: $name) .focused($isFocused) .textFieldStyle(.roundedBorder) Button("フォーカスを外す") { isFocused = false } } .padding() } } |
この例では、isFocused
という状態変数にフォーカスの有無がバインドされています。
ボタンを押すと isFocused = false
となり、キーボードが閉じてフォーカスが外れます。
具体例②:複数の入力欄を切り替える(列挙型で管理)
複数のテキストフィールドを切り替えてフォーカスしたい場合は、列挙型を使うと便利です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
struct ContentView: View { enum Field: Hashable { case username case password } @State private var username = "" @State private var password = "" @FocusState private var focusedField: Field? var body: some View { Form { TextField("ユーザー名", text: $username) .focused($focusedField, equals: .username) SecureField("パスワード", text: $password) .focused($focusedField, equals: .password) Button("パスワード欄へ移動") { focusedField = .password } } } } |
このように @FocusState
を列挙型と組み合わせて使うことで、複数のフィールド間で柔軟にフォーカスを制御できます。
@FocusState の活用シーン
@FocusState
は、単にキーボードの表示・非表示を切り替えるだけでなく、ユーザーの入力体験をスムーズにするために幅広く使えます。
特にフォームや検索UIなど、複数の入力欄を扱う場面では効果的です。
- ログインフォームや複数入力欄で、次の欄に自動でフォーカスを移す
- 初期表示時に特定の欄に自動フォーカスを当てたいとき
- 「完了」ボタンなどでキーボードを閉じたいとき
- フォーカス状態に応じてUI(枠線、背景など)を変えたいとき
これらのシナリオにおいて @FocusState
を活用すると、ユーザーが「次に何をすればいいか」を直感的に理解でき、操作性や入力効率が大きく向上します。
@FocusState を使うときの注意点
非常に便利な一方で、@FocusState
にはいくつかの制約や注意点もあります。
これらを理解しておかないと、意図した挙動にならないケースが出てくるため、実装時に意識しておくことが大切です。
@FocusState
の対象は iOS15 以降のみ対応しています(古いiOSでは使えません)- フォーカスの対象が明確でないと、うまく動かないことがあります
- SwiftUIの一部のView(例:ScrollView内のTextField)では、スクロールと干渉して思うように動かない場合があるため、補助的に
.scrollDismissesKeyboard(.interactively)
などを組み合わせるとよいです
これらを踏まえて使えば、@FocusState
を安定して活用でき、ユーザーにとってストレスのない入力体験を提供できます。
まとめ
今回は @FocusState
について詳しく紹介しました。
@FocusState
は、フォーカス状態を管理するためのSwiftUIのプロパティラッパー.focused(_:)
と組み合わせることで、ビューの状態と入力状態を連動させられる- BoolやEnumで柔軟に制御でき、複数入力欄の切り替えにも対応
- 入力補助、UX向上、自動フォーカスなど多彩な場面で活用できる
フォームや検索UIなど、ユーザー入力のある画面では @FocusState
を使うことで操作性が大きく向上します。
まずは単一のTextFieldから試して、徐々にEnumによる管理や自動切り替えにも挑戦してみましょう。