Sponsor Link
環境&対象
- macOS Ventura 13.3 Beta
- Xcode 14.3 Beta2
- iOS 16.0
willSet/didSet
willSet/didSet は、Swift 言語の持つ Property Observer の1つです。
Swift のドキュメントは、こちら。
struct や class 等の プロパティに値を設定する前後に、指定する処理を行うことができます。
willSet は 設定する直前、didSet は、設定した直後に処理されます。
アプリ向け実装としては、特定のプロパティの変更に応じて付随する処理の実行を行います。
デバッグ時には どのオブジェクトがどのタイミングで プロパティを変更してるかを確認するため等に 使えます。
以下は、Swift の Language Reference に言及されているサンプルです。
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps
上記の例では willSet では カスタムパラメータとして宣言されている newTotalSteps として これから設定される値を参照しています。カスタムパラメータとして宣言していないときは、newValue として参照できます。
didSet では、設定前の値は カスタムパラメータとして宣言していないので、デフォルトの “oldValue” という変数として参照することができます。willSet と同様にカスタムパラメータとして宣言すると指定した名称で参照できます。
なお、willSet では newValue の値を変更することはできません。(let で定義されています)
意味はありませんが、didSet で oldValue を変更することもできません。
なお、didSet では、自処理のなかで プロパティを再度 変更することは可能です。
例えば 設定された値を元に調整した別の値にすることが可能です。
onChange
SwiftUI では didSet と似た感じの機能を持つ View Modifier として、onChange という ViewModifier が用意されています。
Apple のドキュメントは、こちら。
特定の プロパティ等が変更された時に、付随して処理を行いたい時に使用することができます。
ただし、対象は、Equatable に conform している必要があります。
使用例は、以下です。
struct ContentView: View {
@State private var selectedValue: Int = 0
var body: some View {
SomeView()
.onChange(of: selectedValue) { newValue in
// selectedValue と言うプロパティが、設定されたあと、実行される(設定値は、newValue)
// process something
}
}
}
selectedValue という変数が変更された時に、以降の closure が実行されます。
この時に、新しく設定された値は、newValue として受け取ることができます。(該当変数にすでに設定されている値と同じです)
onChange も oldValue を受け取れる
キャプチャを使うことで、didSet と同様に、onChange も変更前の値も受け取ることができるようになっています。
受け取るためには、以下のように記述します。
struct ContentView: View {
@State private var selectedValue: Int = 0
var body: some View {
SomeView()
.onChange(of: selectedValue) { [selectedValue] newValue in
// selectedValue : old Value
// newValue : new value
}
}
}
なお、変更前の値を別変数名で受け取ることも可能です。
struct ContentView: View {
@State private var selectedValue: Int = 0
var body: some View {
SomeView()
.onChange(of: selectedValue) { [myOldValue = selectedValue] newValue in
// myOldValue : old Value
// newValue : new value
}
}
}
ちなみに、onChange は、MainThread で処理されるため、時間のかかる処理を直接実行すると 反応の悪い UI になってしまいますので注意が必要です。
まとめ
willSet/didSet/onChange の使い方を確認しました。
- willSet は、プロパティ変更直前に呼ばれる
- willSet は、newValue という名称の変数で 設定される値を参照できる
- willSet でカスタムパラメータ定義すると好きな変数名で参照できる
- didSet は、プロパティ変更直後に呼ばれる
- didSet は、oldValue という名称の変数で 設定される値を参照できる
- didSet でもカスタムパラメータ定義すると好きな変数名で参照できる
- onChange では、closure に newValue 相当が渡されてくる
- onChange でも、oldValue を取得することができる
- onChange は、MainThread で処理されるので注意が必要
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
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