[SwiftUI] @FocusState の使い方

SwiftUI2021

iOS15/macOS12 で導入される FocusState の使い方を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Monterery beta 5
  • Xcode 13 beta5
  • iOS 15 beta

FocusState

iOS15/macOS12 で、FocusState が導入され、TextField 等の表示要素のフォーカス制御が可能となります。

FocusState の基本的な使用方法を説明します。

FocusState と .focused

FocusState が付与されて定義された変数は、.focused とセットで使うことになります。

Bool で制御する FocusState

ビューの中の1つの表示要素について Focus をセットするかどうかを制御したい時には、Bool 型をもつ FocusState を使います。

この FocusState 変数が .focused を使って関連づけたあとに、変数に true/false をセットすることで、フォーカスを制御できるようになります。

OneTextFieldFocus
OneTextFieldFocus

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/09/09
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    @State private var text: String = "Hello"
    // (1)
    @FocusState private var textField: Bool
    
    var body: some View {
        VStack {
            TextField("text", text: $text)
                .textFieldStyle(.roundedBorder)
                // (2)
                .focused($textField)
            Button(action: {
                // (3)
                textField = true
            }, label: {
                Text("Focus textField/Show keyboard")
            })
                .buttonStyle(.bordered)
            Button(action: {
                // (4)
                textField = false
            }, label: {
                Text("Unfocus textField/Hide keyboard")
            })
                .buttonStyle(.bordered)
            // (5)
            Text("FocusState value: \(textField == true ? "true" : "false" )")
                .padding()
        }.padding()
    }
}
コード解説
  1. FocusState を付与して、フォーカス制御用の変数を定義
  2. TextField に .focused を使用して、フォーカス制御用の変数を関連づけます
  3. ボタン押下時に フォーカス制御用変数に false をセットし、TextField にフォーカスを外します
  4. ボタン押下時に フォーカス制御用変数に true をセットし、TextField にフォーカスをセットします
  5. 確認用に、フォーカス制御用変数の値を表示しています

FocusState で定義された変数を制御することで、.focused が設定されている TextField のフォーカスを制御することができています。

enum で制御する FocusState

フォーカス管理したい表示要素が複数あるときには、enum (等、Hashable) な型を使って、制御することになります。

TwoTextFieldsFocus
TwoTextFieldsFocus

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/09/09
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    @State private var hello: String = "Hello"
    @State private var world: String = "World"
    // (1)
    enum FocusField: String, RawRepresentable {
        case Hello, World
    }
    // (2)
    @FocusState private var focusField: FocusField?
    
    var body: some View {
        VStack {
            TextField("hello", text: $hello)
                .textFieldStyle(.roundedBorder)
                // (3)
                .focused($focusField, equals: .Hello)
            TextField("text", text: $world)
                .textFieldStyle(.roundedBorder)
                // (3)
                .focused($focusField, equals: .World)
            Button(action: {
                // (4)
                focusField = .Hello
            }, label: {
                Text("Focus Hello")
            })
                .buttonStyle(.bordered)
            Button(action: {
                // (4)
                focusField = .World
            }, label: {
                Text("Focus World")
            })
                .buttonStyle(.bordered)
            Button(action: {
                // (4)
                focusField = nil
            }, label: {
                Text("Unfocus textField")
            })
                .buttonStyle(.bordered)
            // (5)
            Text("FocusState value: \(focusField?.rawValue ?? "nil" )")
                .padding()


        }.padding()
    }
}
コード解説
  1. フォーカス先のフィールドを定義する enum です
  2. 定義した enum を使った FocusState を定義します。
  3. 2つの TextField それぞれに、focused 指定をして、enum それぞれの対応する TextField を設定します
  4. ボタン押下時に フォーカス制御用変数に Hello, World, nil をセットすることで、TextField のフォーカスを制御します
  5. 確認用に、フォーカス制御用変数の値を表示しています

FocusState で定義された変数を制御することで、複数の TextField のフォーカスを制御することができています。

まとめ:@FocusState の使い方

@FocusState の使い方
  • 表示制御用変数を @FocusState 指定で宣言する
  • 1つの要素のフォーカスを制御するときは、Bool で使う
  • 複数要素のフォーカスを制御するときは、enum で使う
  • 制御対象の要素は、.focused 指定で関連づける

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です