[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