SwfitUI基础之在多个视图之间共享同一个对象实例

选择建议

1.@ObservedObject:适用于对象实例只需在几个相邻视图间共享,且你想明确控制对象传递的情况。

2.@EnvironmentObject:适合在整个视图层次结构中共享对象,能避免在每个子视图中手动传递对象。

3.单例模式:当你需要在应用的不同部分全局共享一个对象实例,且不依赖 SwiftUI 特定机制时可使用。

1. 使用 @ObservedObject

@ObservedObject 适合在多个视图间共享对象实例,你需手动将对象实例传递给子视图。
示例代码

import SwiftUI
import Combine

// 定义一个遵循 ObservableObject 协议的类
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 协议,包含一个 @Published 属性 sharedData,当该属性变化时会通知视图更新。
  • ParentView:使用 @StateObject 创建并管理 SharedViewModel 实例,点击按钮可更新 sharedData。
  • ChildView:使用 @ObservedObject 接收从父视图传递过来的 SharedViewModel 实例,能显示和响应 sharedData 的变化。

2. 使用 @EnvironmentObject

@EnvironmentObject 能让你在整个视图层次结构中共享对象实例,无需手动在每个子视图中传递。
示例代码

import SwiftUI
import Combine

// 定义一个遵循 ObservableObject 协议的类
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 创建 SharedViewModel 实例,通过 .environmentObject(viewModel) 将该实例注入到视图环境中。
  • ChildView:使用 @EnvironmentObject 从视图环境中获取 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() 创建单例实例,private init() 确保该类不能在外部实例化。
  • ParentView 和 ChildView:都通过 SharedViewModel.shared 访问同一个单例实例,实现数据共享。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容