【iOS】SwiftUI - 05 - State Management

  • 263
  • 0
  • iOS
  • 2022-07-06

上一個章節已經學會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