swift 如何拥有3个重复的EnvironmentObject,但每种类型只能有一个

x6yk4ghg  于 2023-03-07  发布在  Swift
关注(0)|答案(1)|浏览(116)

我有

struct ContentView: View {
    @StateObject var predictService1: PredictService = PredictService()
    @StateObject var predictService2: PredictService = PredictService()
    @StateObject var predictService3: PredictService = PredictService()
}

这些视图是重复的,因为实际上有3个重复的相同视图具有不同的状态。
我可以沿着视图层次结构向下传递这些参数,但是我宁愿这样使用environmentObject

struct MyAPP: App {
    @StateObject var predictService1: PredictService = PredictService()
        @StateObject var predictService2: PredictService = PredictService()
        @StateObject var predictService3: PredictService = PredictService()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(predictService1)
                .environmentObject(predictService2)
                .environmentObject(predictService3)    //these dont work because its only 1 of each type
        }
    }
}

什么是正确的设计?

agxfikkp

agxfikkp1#

以下是我对你的困惑的看法:

import SwiftUI

class PredictService: ObservableObject {
  // ...
  
  // Shared instances
  
  static let service1 = PredictService()
  static let service2 = PredictService()
  static let service3 = PredictService()
}

struct SampleView: View {
  @ObservedObject private var service = PredictService.service1
  
  // ...
}

你(可能)需要解决一些基本问题:
1.对PredictService示例的更新应该能够触发某些 * 视图 * 中的UI更改;

  1. PredictService示例应在应用程序运行期间保留;
  2. PredictService的不同示例应可用于 * 视图 * 层次结构中不同位置的不同视图。
    您的代码通过以下方式解决这些问题:
    1.将PredictService声明为ObservableObject;
    1.将创建的示例存储为@StateObject;
    1.通过 * 环境 * 沿层次结构向下传递它们;
    1.通过使用@EnvironmentObject公开示例。
    这是一种合理的方法,只是环境似乎不是为这种特殊情况设计的。因此,我建议您稍微做些不同的事情:
    1.仍然需要ObservableObject;
    1.将示例存储为全局变量,为了方便和可读性,将它们初始化为PredictService类的静态成员;
    1.只在 * 视图 * 中使用,不需要 * 环境 *;
    1.通过@ObservedObject将它们暴露在 * 视图 * 中。
    注意:这个解决方案与您已经拥有的解决方案没有太大的不同,但是它避免了使用 * environment *。Environment 本质上是一种通过 View 层次结构传递全局变量的方法,因此,如果对全局变量的使用有顾虑的话,这个解决方案与全局变量的使用没有太大的不同。

相关问题