はじめに
業務でソースコードを読む際に出てくると少し調べるのに時間をかけてしまうので基本形だけでも調べなくてもいいようにアウトプットしておきます。
できること
- ドラッグやスワイプに反応して状態を更新することができる
- データの変更があったタイミングで変更があったものを新しい値として使用できる
- バリデーションなどを入力後に即座に実行できる
例
例えばこんなテキストフィールドがあったとします。
struct ContentView: View {
// 入力した値をもつ変数
// 最初は空文字なので""としてます。
@State var text: String = ""
var body: some View {
VStack {
TextField("入力してね", text: $text)
}
}
}
ここで入力するたびにデバックエリアにprintしたいとき、入力するたびにバリデーションを実行したいときなどに使えるのが.onChange
です
以下のように編集しましょう
TextField("入力してね", text: $text)
.onChange(of: text) {
print(text)
}
これでビルドして試してみると入力するたびにprintされるのがわかります。
今回はprintの例を上げましたが、一般化すると以下のようになります。
.onChange(of: [変更を監視したい変数]) {
// 更新された変数を用いて実行したい処理
}
-
// 更新された変数を用いて実行したい処理
の部分は[変更を監視したい変数]
をそのまま使って大丈夫です。 - iOS17以降は
onChange(of: ) { _ in }
は非推奨となりました。
そのほか
状態を監視して変更があったら更新、何か処理をするモディファイアはいろいろあります。
例文も込みで紹介していきます
テキストフィールド
-
.onEditingChanged
- テキストフィールドの編集が完了した時に実行される処理
- 入力欄からカーソル?を離した時に発火(フォーカスアウト)
TextField("Enter text", text: $text)
.onEditingChanged { isEditing in
print("Editing started: \(isEditing)")
}
タップ
-
.onTapGesture
- タップが検知された時に実行される処理
Text("Tap me")
.onTapGesture {
print("Text tapped!")
}
-
.onLongPressGesture
- 長押しのジェスチャーが検出された時に実行される処理
Text("Long press me")
.onLongPressGesture {
print("Text long pressed!")
}
スクロール
-
.onScroll
- スクロールが発生した時呼び出される処理
- スクロールの方向などを検知することはできない
ScrollView {
VStack {
ForEach(0..<50) { index in
Text("Item \(index)")
.padding()
}
}
.onScroll {
print("Scrolling detected!")
}
}
-
.gesture
- スクロールのイベントを検知することができる
-
.onScroll
と違って方向を検知することができる - 例は右方向の例
Rectangle()
.fill(Color.blue)
.frame(width: 100, height: 100)
.gesture(
DragGesture()
.onChanged { value in
// 右方向へのスクロールを検知
if value.translation.width > 0 {
print("Dragging right!")
}
}
)