選擇建議
1.@ObservedObject:適用于對象實例只需在幾個相鄰視圖間共享,且你想明確控制對象傳遞的情況。
2.@EnvironmentObject:適合在整個視圖層次結構中共享對象,能避免在每個子視圖中手動傳遞對象。
3.單例模式:當你需要在應用的不同部分全局共享一個對象實例,且不依賴 SwiftUI 特定機制時可使用。
1. 使用 @ObservedObject
@ObservedObject 適合在多個視圖間共享對象實例,你需手動將對象實例傳遞給子視圖。
示例代碼
import SwiftUI
import Combine
// 定義一個遵循 ObservableObject 協(xié)議的類
class SharedViewModel: ObservableObject {
@Published var sharedData: String = "初始數據"
func updateData() {
sharedData = "更新后的數據"
}
}
// 父視圖
struct ParentView: View {
@StateObject private var viewModel = SharedViewModel()
var body: some View {
VStack {
Text("父視圖: \(viewModel.sharedData)")
Button("更新數據") {
viewModel.updateData()
}
ChildView(viewModel: viewModel)
}
}
}
// 子視圖
struct ChildView: View {
@ObservedObject var viewModel: SharedViewModel
var body: some View {
Text("子視圖: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代碼解釋
- SharedViewModel:遵循 ObservableObject 協(xié)議,包含一個 @Published 屬性 sharedData,當該屬性變化時會通知視圖更新。
- ParentView:使用 @StateObject 創(chuàng)建并管理 SharedViewModel 實例,點擊按鈕可更新 sharedData。
- ChildView:使用 @ObservedObject 接收從父視圖傳遞過來的 SharedViewModel 實例,能顯示和響應 sharedData 的變化。
2. 使用 @EnvironmentObject
@EnvironmentObject 能讓你在整個視圖層次結構中共享對象實例,無需手動在每個子視圖中傳遞。
示例代碼
import SwiftUI
import Combine
// 定義一個遵循 ObservableObject 協(xié)議的類
class SharedViewModel: ObservableObject {
@Published var sharedData: String = "初始數據"
func updateData() {
sharedData = "更新后的數據"
}
}
// 父視圖
struct ParentView: View {
@StateObject private var viewModel = SharedViewModel()
var body: some View {
VStack {
Text("父視圖: \(viewModel.sharedData)")
Button("更新數據") {
viewModel.updateData()
}
ChildView()
}
.environmentObject(viewModel)
}
}
// 子視圖
struct ChildView: View {
@EnvironmentObject var viewModel: SharedViewModel
var body: some View {
Text("子視圖: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代碼解釋
- SharedViewModel:同上述示例。
- ParentView:使用 @StateObject 創(chuàng)建 SharedViewModel 實例,通過 .environmentObject(viewModel) 將該實例注入到視圖環(huán)境中。
- ChildView:使用 @EnvironmentObject 從視圖環(huán)境中獲取 SharedViewModel 實例,無需手動傳遞。
3. 使用單例模式
單例模式可確保一個類只有一個實例,并提供一個全局訪問點。
示例代碼
import SwiftUI
import Combine
// 定義一個單例類
class SharedViewModel: ObservableObject {
static let shared = SharedViewModel()
private init() {}
@Published var sharedData: String = "初始數據"
func updateData() {
sharedData = "更新后的數據"
}
}
// 父視圖
struct ParentView: View {
@ObservedObject private var viewModel = SharedViewModel.shared
var body: some View {
VStack {
Text("父視圖: \(viewModel.sharedData)")
Button("更新數據") {
viewModel.updateData()
}
ChildView()
}
}
}
// 子視圖
struct ChildView: View {
@ObservedObject private var viewModel = SharedViewModel.shared
var body: some View {
Text("子視圖: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代碼解釋
- SharedViewModel:通過 static let shared = SharedViewModel() 創(chuàng)建單例實例,private init() 確保該類不能在外部實例化。
- ParentView 和 ChildView:都通過 SharedViewModel.shared 訪問同一個單例實例,實現數據共享。