同一 EnvironmentObject 的多个实例

Posted

技术标签:

【中文标题】同一 EnvironmentObject 的多个实例【英文标题】:Multiple Instance of the Same EnvironmentObject 【发布时间】:2020-10-12 19:29:48 【问题描述】:

我有一个@EnvironmentObject

@main
struct Image_WidgetApp: App 
    @State var imageNumString = ""
    @State var showDetailView = false  
    @EnvironmentObject var userData: UserData
    var body: some Scene         
        WindowGroup 
            if(!showDetailView)
                ContentView()
                    .onOpenURL  url in
                        imageNumString = url.absoluteString
                        showDetailView = true
                    
                    .environmentObject(UserData())   // First instance of the environmentObject
            
            else
                ImageDetailView( mySubstring: $imageNumString, doneFunction: 
                    self.showDetailView = false
                )                                    
                .environmentObject(UserData())   // Second instance of the environmentObject
            
        
    

如果用户通过应用程序图标打开应用程序,我将ContentView() 设置为活动状态。

如果用户通过小部件打开应用程序,我通过在onOpenURL 中设置showDetailView = true 来设置ImageDetailView() 处于活动状态。

到目前为止一切都很好。

问题可能是我有同一个 environmentObject 的 2 个不同实例。见https://github.com/peterfriese/Swift-EnvironmentObject-Demo

因为当我在任何视图中更改任何内容时,另一个视图不会意识到这一点。

为了解决这个问题,我尝试使用NavigationLink,因为这种方法旨在将ImageDetailView() 作为子视图推送,但没有机会。小部件单击不会将 ImageDetailView() 推送到导航堆栈。

@main
struct Image_WidgetApp: App 
    @State var imageNumString = ""
    @State var showDetailView = false  
    @EnvironmentObject var userData: UserData
    var body: some Scene         
        WindowGroup 
                ContentView()
                    .onOpenURL  url in
                        imageNumString = url.absoluteString
                        showDetailView = true
                        if imageNumString.count > 0

                            imageNumString = url.absoluteString
            
                            NavigationLink(destination: ImageDetailView(mySubstring: $imageNumString), isActive: $showDetailView) 
                                EmptyView()
                             .hidden()
                        
                        .environmentObject(UserData())  
            
        
         

如何将@EnvironmentObject 用作单个实例?

【问题讨论】:

【参考方案1】:

如何将@EnvironmentObject 用作​​单个实例?

您可以创建一个全局UserData 实例并在必要时注入:

@main
struct Image_WidgetApp: App  
    @StateObject var userData = UserData()

    var body: some Scene         
        WindowGroup 
                FirstView()
                    .environmentObject(userData)
                SecondView()
                    .environmentObject(userData)
            
        
         

关于从 App/Widget 启动不同的视图,请参阅:

Detect app launch from WidgetKit widget extension

【讨论】:

以上是关于同一 EnvironmentObject 的多个实例的主要内容,如果未能解决你的问题,请参考以下文章

ObjectBinding 和 EnvironmentObject 有啥区别?

访问和操作 EnvironmentObject 中的数组项

SwiftUI - 在 ObservableObject 类/依赖注入中使用 EnvironmentObject

在 watchOS 中使用 environmentObject

SwiftUI:可以访问祖先自定义`@EnvironmentObject`?如果是,如何?

SwiftUI View 协议中的 EnvironmentObject