SwiftUI 中的环境对象 [英] EnvironmentObject in SwiftUI

查看:37
本文介绍了SwiftUI 中的环境对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To my knowledge, I should be able to use EnvironmentObject to observe & access model data from any view in the hierarchy. I have a view like this, where I display a list from an array that's in LinkListStore. When I open AddListView and add an item, it correctly refreshes the ListsView with the added item. However, if I use a PresentationButton to present, I have to do AddListView().environmentObject(listStore), otherwise there will be a crash when showing AddListView. Is my basic assumption correct (and this is behavior is most likely a bug) or am I misunderstanding the use of EnvironmentObject?

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

Basically: @State to bind a variable to a view in the same View (e.g. $text to TextField), @ObjectBinding/BindableObject to bind variables to other Views, and EnvironmentObject to do the same as @ObjectBinding but without passing the store object every time. With this I should be able to add new items to an array from multiple views and still refresh the Lists View correctly? Otherwise I don't get the difference between ObjectBinding and 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

推荐答案

来自 Apple 文档 EnvironmentObject:

From Apple docs EnvironmentObject:

环境对象一种动态视图属性,它使用祖先视图提供的可绑定对象在可绑定对象更改时使当前视图无效.

EnvironmentObject A dynamic view property that uses a bindable object supplied by an ancestor view to invalidate the current view whenever the bindable object changes.

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

It translates as the binding affects the current view hierarchy. My guess is that when you are presenting a new view via PresentationButton, you are creating a new hierarchy, which is not rooted in your view -- the one you have supplied the object to. I'd guess the workaround here is to add the object to the "global" environment by implementing a struct that confirms to the EnvironmentKey protocol.

这篇关于SwiftUI 中的环境对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆