上一個章節已經學會value type 可以使用@State 和@Binding 屬性,讓值改變時可以連動不同畫面的顯示更新
在這個章節可以進一步了解要如何讓reference type 達到相同的連動效果,動態反應在各個關聯的View 上
Making Classes Observable
如何讓參考型別物件也可以連動
@State 和@Binding 只對value type 有效
如果要對reference types 需要宣告繼承 @ObservedObject
並且指定屬性為@Published
class ScrumTimer: ObservableObject {
@Published var activeSpeaker = ""
@Published var secondsElapsed = 0
@Published var secondsRemaining = 0
// ...
}
如同@State 一般,宣告物件有@StateObject 屬性,使該物件在值改變時得以連動到畫面的更新
struct MeetingView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
// 將宣告為@StateObject 的scrumTimer 物件傳遞到ChildView 裡面
ChildView(timer: scrumTimer)
}
}
// ...
}
當這個scrumTimer 物件傳給下一個View,需要在下一個View 宣告有@ObservedObject 屬性
struct ChildView: View {
@ObservedObject var timer: ScrumTimer
// ...
}
以上的方法需要透過建構子傳入,也可以使用environmentObject 搭配@EnvironmentObject 屬性
如此物件就像全域變數不需要特別注入也可以使用
struct ParentView: View {
@StateObject var scrumTimer = ScrumTimer()
var body: some View {
VStack {
ChildView()
.environmentObject(scrumTimer)
}
}
// ...
}
struct ChildView: View {
@EnvironmentObject var timer: ScrumTimer
// ...
}
Responding to Events
當監控的值發生改變時,利用事件進行相對應處理
簡單來說,View 生命週期的事件有三個
- onAppear(perform:) 畫面出現前時觸發
- onDisappear(perform:) 畫面消失後時觸發
- task(priority:_:) 畫面出現前以非同步觸發
詳細作用還待探討….
Managing State and Life Cycle
實作出更好的畫面連動效果,以及套用播放聲音相關功能
未完待續…
References:
https://developer.apple.com/tutorials/app-dev-training/making-classes-observable
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app