【问题标题】:Passing different instances of same Model to same SwiftUI View struct将相同模型的不同实例传递给相同的 SwiftUI 视图结构
【发布时间】:2020-04-09 03:09:14
【问题描述】:

我有一个基于 Tab 的应用,用 Swift 实现,并使用 SwiftUI。

对于 2 个选项卡,我想显示基于相同 SwiftUI 结构的列表,显示同一类的不同实例。

在 SceneDelegate 中,

    let naughtyModel = SantaListModel(title: "Naughty")
    let niceModel    = SantaListModel(title: "Nice")

    // Create the SwiftUI view that provides the window contents.
    let contentView = ContentView()
        .environmentObject(naughtyModel)
        .environmentObject(niceModel)

    ...

那么,

struct ContentView: View {
    @State private var selection = 0

    @EnvironmentObject var naughtyModel: SantaList
    @EnvironmentObject var niceModel: SantaList

    var body: some View {
        TabView(selection: $selection){
            SantaListView().environmentObject(naughtyModel)
                .font(.title)
                .tabItem {
                    VStack {
                        Text(naughtyModel.title)
                    }
                }
                .tag(0)
            SantaListView().environmentObject(niceModel)
                .font(.title)
                .tabItem {
                    VStack {
                        Text(niceModel.title)
                    }
                }
                .tag(1)
            }
        }
   }

到目前为止一切似乎都很好,但是当我实现 SantaListView,一个显示不同实例的共享结构实现时,计划出错了......

struct SantaListView: View {

    @EnvironmentObject var santaListModel: SantaList // <<< the problem: naughty or nice?

    var body: some View {
        NavigationView() {
            VStack {
            }
           .navigationBarTitle(Text(santaListModel.title))
        }
    }
}

在SantaList类实现中,如何引用具体的@EnvironmentVariable,使得上面的santaListModel是指具体的实例naughtyModel或者niceModel?

提前致谢。

【问题讨论】:

  • 不是很清楚为什么......但这是不同的问题。 如何 modelA 与modelB 不同?如果您需要在MyModelView 中有条件地做某事,则将该条件放入构造函数参数中。
  • 它们是同一个模型的两个实例,持有不同的数据列表,比如说圣诞老人的淘气列表和圣诞老人​​的好列表;-)

标签: swift swiftui


【解决方案1】:

我建议您简单地为模型创建两个子类:

class NaughtyList: SantaListModel {
  init() {
    super.init(title: "Naughty")
  }
}

class NiceList: SantaListModel {
  init() {
    super.init(title: "Nice")
  }
}

通过这样做,两个列表都可以存储在环境中而不会发生冲突。 SwiftUI 唯一需要区分环境对象的是类。因此,有单独的类很重要。

【讨论】:

  • 感谢您的回复。似乎 SwiftUI 方法的一个真正不足之处在于,我们必须仅进行子类化才能将同一模型的不同实例传递给一个公共视图。但是共享视图如何知道它正在接收哪些模型 - 似乎我们又回到了原点?
  • @Snips 我想您已将对象作为NaughtyList()NiceList() 添加到环境中。在需要调皮列表的视图中,您将指定相应的类型:var santaListModel: NaughtyList 而不是SantaListModel。应该这样做...根据您指定的类型,SwiftUI 将从环境中获取正确的对象。
  • 我可能误解了你的建议,但重点是我想要一个通用的共享视图实现来显示同一模型的不同实例。另一个例子是音乐播放列表的不同实例——这似乎是一个非常普遍的要求。我有一个可行的解决方案,它从上面传递一个不同的实例,但 receives 它是 @ EnvironmentObject var aModelInstance: SantaListModel - 它显然根据传递的内容与对象类型匹配,但充其量看起来很奇怪.
  • @Snips 啊...对不起,我误解了目的。如果你想为不同的目的使用相同的视图(=不同数据的含义),你不应该使用@EnvironmentObject。只需使用@Binding 或常规变量(如果您不需要修改子视图中的数据)。由父视图决定目的是显示“niceList”还是“naughtyList”。例如。在ContentView 中使用SantaListView(santaListModel: niceList)
  • 谢谢你——现在你说这句话的意义非常明显!我会在实践中尝试并报告。
猜你喜欢
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多