[SwiftUI] iOS17対応版!`onChange(of:perform:)`の非推奨と新しい使い方まとめ
SwiftUIのアップデートで注目すべきポイントのひとつ、
onChange(of:perform:)
がiOS17から非推奨(deprecated)になりました。
これにより、今までの書き方が整理され、
よりシンプルで直感的なAPIへと進化しています。
onChange
の使い方
新しいクロージャの形式は「0個」か「2個」
新しいonChange
では、クロージャの引数が「なし」または「2つ」に統一されました。
1. 引数なしの場合
変化前後の値を使わない場合は、次のように記述します。
.onChange(of: value) {
// 変化があったら実行
}
2. 引数2つ(oldValue, newValue)の場合
変化前と変化後の両方の値を使いたい場合はこちら。
.onChange(of: value) { oldValue, newValue in
// oldValue と newValue を使って処理
}
状態の移り変わりをより繊細に追跡できるので、
データ比較や特殊な条件分岐に便利です。
initial
オプションとは?
新たに、initial: true
オプションが追加されました。
これを指定すると、ビューの初回表示時にもクロージャが実行されます。
.onChange(of: value, initial: true) {
// 初回表示時も実行される
}
initial: true
を使うときの注意点
初回実行時は oldValue
と newValue
が同じ値になるため、
差分検出ロジックには一工夫が必要です。
(差がない場合でもクロージャは呼び出されます)
コード比較:変更前と変更後
変更前:
.onChange(of: selectedIcon) { newValue in
if newValue == "Default" {
changeAppIcon(to: nil)
} else {
changeAppIcon(to: newValue)
}
}
変更後:
.onChange(of: selectedIcon) {
if selectedIcon == "Default" {
changeAppIcon(to: nil)
} else {
changeAppIcon(to: selectedIcon)
}
}
コードがよりスッキリし、読みやすさも向上します。
oldValue
とnewValue
を活用しよう
iOS17以降、onChange
のクロージャでoldValue
とnewValue
の両方が取れるようになり、
状態の変化をより細かくハンドリングできるようになりました。
例えば、アプリのライフサイクル管理ではこう使えます。
.onChange(of: scenePhase) { oldValue, newValue in
if oldValue == .active && newValue == .inactive {
// アクティブから非アクティブへの遷移を検知
}
}
これにより、以前のように手動で状態を保存・比較する手間が減り、
コードの保守性も向上します。
まとめ:SwiftUIをもっと快適に
今回の変更は「クロージャの書き方が変わった」くらいの感覚でOKです。
既存コードもそのまま動く場合が多く、
移行はそこまで大がかりにはなりません。
とはいえ、新しい書き方に慣れておくことで、
これからのSwiftUI開発がさらに快適になること間違いなし。
ぜひこの機会に、新しいonChange
スタイルをマスターしておきましょう!
Discussion