SwiftUI 3.0 で @FocusState と言うフォーカス対象を管理する状態変数が追加されたので試してみました。
動作確認環境
【SwiftUI 3.0】TextField のフォーカスを管理する方法
設定手順
対象のTextFieldをenumで定義
管理対象となる TextField を識別するために下記のような enum を定義します。
enum FocusTextFields {
case email
case password
}
@FocusState 変数の宣言
enum で定義した型の @FocusState 変数を用意します。
@FocusState var focusState: FocusTextFields?
.focused プロパティで TextField に紐付ける
@FocusState 変数と enum を .focused プロパティでTextFieldに紐付けます。
TextField("Email", text: $emailText)
.focused($focusState, equals: .email)
以上のような設定をするだけで、@FocusState で宣言した変数の値を変更することでフォーカス先を移動することができるようになります。
サンプルコード
冒頭のgif動画の全体コードは以下の通りです。
Button を押下した時にそれぞれの TextField にフォーカスを移しています。
struct ContentView: View {
enum FocusTextFields {
case email
case password
}
@FocusState private var focusState: FocusTextFields?
@State private var emailText = ""
@State private var passwordText = ""
var body: some View {
VStack {
TextField("Email", text: $emailText)
.focused($focusState, equals: .email)
SecureField("Password", text: $passwordText)
.focused($focusState, equals: .password)
VStack {
Button("Focus Email", action: {
focusState = .email
})
Button("Focus Password", action: {
focusState = .password
})
}
}
.padding()
.textFieldStyle(.roundedBorder)
}
}
画面表示時にフォーカスするには?
@FocusState 変数に初期値を与えようとするとビルドエラーとなってしまいます。
そのため、画面表示タイミングで任意の TextField にフォーカスを当てるには onAppear でセットする必要があります。
但し注意点として、onAppear が呼ばれてから少し間を置かないとうまくフォーカスしてくれないようなので、以下のようにすると良いでしょう。
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
focusState = .password
}
}
以上
macOS Monterey 12.1
Xcode 13.2.1
iOS 15.2(iPhone SE(2nd Generation)シミュレータ)