【问题标题】:EnvironmentObject in SwiftUISwiftUI 中的环境对象
【发布时间】:2019-10-23 19:24:00
【问题描述】:

据我所知,我应该能够使用 EnvironmentObject 从层次结构中的任何视图观察和访问模型数据。我有一个像这样的视图,我在其中显示来自 LinkListStore 中的数组的列表。当我打开 AddListView 并添加一个项目时,它会使用添加的项目正确刷新 ListsView。但是,如果我使用PresentationButton来呈现,我必须做AddListView().environmentObject(listStore),否则在显示AddListView的时候会出现crash。我的基本假设是否正确(这种行为很可能是一个错误)还是我误解了 EnvironmentObject 的使用?

基本上:@State 将变量绑定到同一 View 中的视图(例如 $text 到 TextField),@ObjectBinding/BindableObject 将变量绑定到其他 View,EnvironmentObject 与 @ObjectBinding 执行相同但不传递每次都存储对象。有了这个,我应该能够从多个视图将新项目添加到数组中,并且仍然正确刷新列表视图?否则我不明白 ObjectBinding 和 EnvironmentObject 之间的区别。

struct ListsView : View {

@EnvironmentObject var listStore: LinkListStore

var body: some View {
    NavigationView {
        List {

            NavigationButton(destination: AddListView()) {
                HStack {
                    Image(systemName: "plus.circle.fill")
                        .imageScale(.large)
                    Text("New list")
                }
            }

            ForEach(listStore.lists) { list in
                HStack {
                    Image(systemName: "heart.circle.fill")
                        .imageScale(.large)
                        .foregroundColor(.yellow)
                    Text(list.title)
                    Spacer()
                    Text("\(list.linkCount)")
                }
            }
            }.listStyle(.grouped)
        }

    }
}

#if DEBUG
struct ListsView_Previews : PreviewProvider {
    static var previews: some View {
        ListsView()
            .environmentObject(LinkListStore())
    }
}
#endif

【问题讨论】:

  • 如果我必须通过 .environmentObject 将后者传递给下一个视图,我似乎在理解 BindableObject 和 EnvironmentObject 之间的区别时遇到了同样的问题。假设我有一个从视图 A 到 B 等到视图 F 的向导,这是否意味着我总是必须传递 environmentObject? @Nico 你有没有发现更多关于这个主题的信息?

标签: dataflow swiftui


【解决方案1】:

来自 Apple 文档EnvironmentObject

环境对象 一个动态视图属性,它使用由祖先视图提供的可绑定对象来在可绑定对象发生更改时使当前视图无效。

它转换为绑定影响当前视图层次结构。我的猜测是,当您通过 PresentationButton 呈现新视图时,您正在创建一个新的层次结构,该层次结构并不植根于您的视图——您提供对象的那个。我猜这里的解决方法是通过实现一个确认EnvironmentKey 协议的结构来将对象添加到“全局”环境中。

【讨论】:

  • 我在文档中也读到了这一点,但是如果 environmenObject 应该“由祖先视图提供”,它如何真正区别于 BindableObject - 我必须将 View Hierarchies 传递为好吧。
  • 我想您必须手动将 BindableObject 传递给层次结构中的每个视图(例如,作为构造函数参数),而您可以指定一次 environmentObject(在根目录),它将存在于每个视图中跨越层次结构。
  • 如何使用环境传递标准 Swift 对象,例如 IntString
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多