Sponsor Link
環境&対象
- macOS Monterey 13 Beta9
- Xcode 14.1 beta 3
- iOS 16.0
FocusedValue/FocusedBindingの使い所
FocusState は、ビューがフォーカスされているかどうかを そのビュー中で 参照することができました。
FocusedValue / FocusedBinding は、もうすこし拡張された機能です。
ビューがフォーカスされたことをきっかけに、特定のデータを設定することができ、参照することができるようになります。
データの使われ方に応じて、FocusedValue, FocusedBinding が用意されています。
使用シーンとしては、以下のようなシーンが考えられます。
・フォーカスされているビューに応じて、切り替えられるメニュー/コマンド (Apple ドキュメントによく出てきます)
・フォーカスされているテキストフィールドに応じて、内容が切り替えて表示される補助ビュー
この記事では、FocusedValue の使い方を説明していきます。FocusedBinding についての記事は、別途 作成予定です。
FocusState は、以下の記事で説明しています。
[SwiftUI] @FocusState の使い方
FocusedValue
この記事では、FocusedValue を説明します。
FocusedValue でアクセスする変数の定義
FocusedValue を使用するためには FocusedValue として設定する/アクセスされるためのデータを定義することが必要です。
FocusedValue のデータは、内部的には、キーを使用して管理されますので、まずは、キーを定義することが必要です。
以下のように、FocusedValueKey に準拠する形で定義すると MyFocusedDataKey というキーが定義できます。
扱う型を typealias を使って、Value に設定します。以下の例では Int 型です。
struct MyFocusedDataKey: FocusedValueKey {
typealias Value = Int
}
次に、キーを使ってアクセスされた時の処理を定義します。FocusedValues の extension として定義します。
extension FocusedValues {
var myIntData: MyFocusedDataKey.Value? {
get { self[MyFocusedDataKey.self] }
set { self[MyFocusedDataKey.self] = newValue }
}
}
定義したキーを使用して管理されていることがわかると思います。
データ型が Optional である理由は、フォーカスされていないときには、nil が設定されるためです。
ちなみに、この処理 どこかで見たことがある気がすると思います。
ほとんど、environment と同じです。
environment 変数では、KeyPath の型が、WritableKeyPath<EnvironmentValue,V> となっていますが、FocusedValue では、WritableKeyPath<FocusedValues,Value?> となっています。
値設定の仕方
FocusedValue で扱われる値を設定するための View Modifier が用意されています。
.focusedValue です。
func focusedValue(
_ keyPath: WritableKeyPath,
_ value: Value
) -> some View
Apple のドキュメントは、こちら。
以下のような形で、FocusedValue を設定することになります。
TextField("Title", $title)
.focusedValue(\.myData, 2)
気をつけなければいけない点は、”ビューが フォーカスを受けたとき”に 値が設定される という点です。
つまりフォーカスを受けなければ、値が設定されることはありません。
つまり、Optional である型に nil が設定されているということになります。
アクセス方法
設定された FocusedValue にアクセスするには、Property Wrapper である @FocusedValue を使います。
データ型が Optional であるため、確認してから 使用しています。
struct MyView: View {
@FocusedValue(\. myIntData) var intValue
var body: some View {
if let value = intValue {
Text("intValue = \(intValue)")
} else {
Text("No Value")
}
}
}
FocusedValue のデータは、フォーカスされたビューが設定することによって設定されるため、まだフォーカスされていない状態であれば、nil となっているため、”No Value” が表示されることになります。
実装例
以下のようなアプリを作って動作を確認しました。
TextField 3つと Button と SubView で構成されています。
動画で動作を確認してもらうと、以下の点を確認することができます。
- TextField がフォーカスを受けると、それぞれの focusedValue で設定されている 1, 2, 3 がスクリーン下部に表示されるので、フォーカスを受けるごとに FocusedValue が更新されていることがわかる
- TextField でなく、Button がフォーカスを受けると、focusedValue が設定されないため、FocusedValue には、nil が設定される
- 下位ビューでない、SubView が 受け取れていることからも 親子関係の無いビューからでも FocusedValue は、受け取ることができる
以下は使用したコードです。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2022/09/30
// © 2022 SmallDeskSoftware
//
import SwiftUI
struct MyFocusedDataKey: FocusedValueKey {
typealias Value = Int
}
extension FocusedValues {
var myIntData: MyFocusedDataKey.Value? {
get { self[MyFocusedDataKey.self] }
set { self[MyFocusedDataKey.self] = newValue }
}
}
struct ContentView: View {
var body: some View {
VStack {
FieldsView()
Button(action: {}, label: {Text("DummyButton")})
SubView()
}
.padding()
}
}
struct FieldsView: View {
@State private var text1 = ""
@State private var text2 = ""
@State private var text3 = ""
var body: some View {
Group {
TextField("Text1", text: $text1)
.focusedValue(\.myIntData, 1)
TextField("Text2", text: $text2)
.focusedValue(\.myIntData, 2)
TextField("Text3", text: $text3)
.focusedValue(\.myIntData, 3)
}.padding()
}
}
struct SubView: View {
@FocusedValue(\.myIntData) var intValue
var body: some View {
GroupBox("SubView") {
if let value = intValue {
Text("intValue = \(value)")
} else {
Text("No Value")
}
}
}
}
まとめ
FocusedValue の使い方を説明しました。
- FocusedValueKey に準拠したキーを定義する, Value に型も設定する
- FocusedValues の extension にアクセスを定義する
- focusedValue は、View がフォーカスを受けないと値をセットしない
- focusedValue は、フォーカスを失うと nil になる
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMastery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link