前回の記事
iOS App Dev Tutorialsを読んでみた。その8
前回の記事を読んだ後に、この記事をご覧ください。
今回の範囲
Making classes observable(クラスを観察可能にする)
9回目は、アプリのユーザー インターフェイスの信頼できる情報源として参照型を定義する方法を学びます。
内容の要約
1.参照型の操作
以前のチュートリアルでは、@State属性をプロパティに追加して、そのプロパティを真実の情報源として扱う方法を学びました。ただし、@Stateプロパティラッパーは、値型(構造体や列挙型など)にのみ適用できます。SwiftUIは、クラス型を真実の情報源として使うためのプロパティラッパーとして、ObservedObject、@StateObject、@EnvironmentObjectを提供しています。これらのラッパーをクラスで使うには、そのクラスを監視可能にする必要があります。
2.クラスを観測可能にする
プロトコルを採用することでクラスを監視することができます。また変更時にUIを更新する必要があるプロパティを特定することができます。次に、各プロパティ宣言にObservableObject@Published属性を追加します。
次のスタータープロジェクト(ScrumTimer)には、毎日のスクラムミーティングの時間を管理するクラスが含まれています。
class ScrumTimer: ObservableObject {
@Published var activeSpeaker = ""
@Published var secondsElapsed = 0
@Published var secondsRemaining = 0
// ...
}
次のチュートリアルのスタータープロジェクトには、毎日のスクラムミーティングの時間を管理するScrumTimerクラスが含まれています。このクラスは、スクラムセッション中に更新されるいくつかの公開プロパティを宣言します。
3.オブジェクトの変更を監視する
SwiftUIでは、Observableオブジェクトを監視するために、プロパティ宣言に次の中の、ObservedObject、StateObject、Environment、のいずれかの属性を追加することができます。これらの属性を使用すると、ビュープロパティが新しいデータソースを作成します。App、Scene、またはView内で、@StateObject属性を使用して、Observableオブジェクトを作成します。システムはオブジェクトを初期化し、他のビューに渡すために保持します。
struct MeetingView: View {
@StateObject var scrumTimer = ScrumTimer()
// ...
}
ObservedObjectプロパティラッパーを使用して、ビューがアプリ、シーン、ビューなどの親ソースからオブジェクトを受け取ったことを示します。この親構造はオブジェクトを作成し所有するので、子ビューはObservedObjectの初期値をしません。
struct ChildView: View {
@ObservedObject var timer: ScrumTimer
// ...
}
observableオブジェクトのインスタンスをビューのイニシャライザーに渡します。
struct MeetingView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
ChildView(timer: scrumTimer)
}
}
// ...
}
複雑なビュー階層でObservableオブジェクトを共有するには、@EnvironmentObjectを使用します。そのため、オブジェクトを環境に配置して、イニシャライザ経由で渡す必要はありません。environmentObjectビュー修飾子は、ビューの環境にオブジェクトを配置します。
struct ParentView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
ChildView()
.environmentObject(scrumTimer)
}
}
// ...
}
struct ChildView: View {
var body: some View {
GrandchildView()
}
}
@EnvironmentObjectプロパティラッパーを使用して、ChildViewの子のオブジェクトにアクセスすることができます。
struct GrandchildView: View {
@EnvironmentObject var timer: ScrumTimer
// ...
}
EnvironmentObjectを使用すると、中間ビューに不要な依存関係を持たずに済みます。ParentViewとGrandchildViewはScrumTimerに依存しますが、ChildViewは依存しません。そのため、このモジュールでは@EnvironmentObjectは使用されず、他のプロパティラッパーと同様に、"Managing model data in your app"を参照します。
4.まとめ
SwiftUIでスクラムディンガーのUIにデータを接続するために様々なツールを使用し、参照型の操作方法を学びました。次の記事では、SwiftUIアプリとビューのライフサイクルについて学び、MeetingTimerを使用して公開された会議のプロパティを監視するために@StateObjectをインスタンス化します。