首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在视图中重新实例化@EnvironmentObject对象

在视图中重新实例化@EnvironmentObject对象
EN

Stack Overflow用户
提问于 2020-05-16 03:42:08
回答 1查看 43关注 0票数 1

在我的应用程序中,我需要通过轻触按钮来重新实例化一个@EnvironmentObject。哪里是做这件事的合适地点呢?

这是我的视图截图-在存档对象列表中,我希望拥有不可变的对象。因此,当我点击Archive Object时,我希望将当前对象添加到数组中,并创建一个新的当前对象。

该应用程序的简化版本如下所示。

我在SceneDelegate中实例化了对象

代码语言:javascript
复制
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    var myObject = MyObject()
    let myObjects = MyObjects()

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        let contentView = ContentView()
            .environmentObject(myObject)
            .environmentObject(myObjects)

        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }

    //.....
}

以下是我的模型:

代码语言:javascript
复制
class MyObject: ObservableObject, Identifiable {
    @Published var id = UUID()
}

class MyObjects: ObservableObject {
    @Published var values: [MyObject] = [
        MyObject(),
        MyObject()
    ]
}

在我看来,我需要将当前对象放到一个(存档)数组中,然后创建一个新的当前对象进行操作。这是我正在尝试的:

代码语言:javascript
复制
struct ContentView: View {

    @EnvironmentObject var currentObject: MyObject
    @EnvironmentObject var objects: MyObjects

    var sceneDelegate: UISceneDelegate {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
            let sd = windowScene.delegate as? SceneDelegate else { fatalError() }
        return sd
    }

    var body: some View {
        VStack {
            Form {
                Section(header: Text("Current Object")) {
                    Text(currentObject.id.uuidString)
                }
                Section(header: Text("Archived Objects")) {
                    List(objects.values, id: \.id) { object in
                        Text(object.id.uuidString)

                    }
                    Button(action: {
                        self.objects.values.append(self.currentObject)

// as the environment object is get only, I cannot reinstantiate it here...
//                        self.currentObject = MyObject()
                    }) {
                        Text("Archive Object")
                    }
                }
            }

            Spacer()
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-16 03:50:40

这是一个解决方案。请参阅内联注释。

使用Xcode11.4/ iOS 13.4进行测试

代码语言:javascript
复制
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {

        // Usage
        ContentView(current: MyObject())
            .environmentObject(MyObjects())
    }
}


struct ContentView: View {
    @EnvironmentObject var objects: MyObjects
    @State private var current: MyObject        // tracks current

    init(current: MyObject) {
        _current = State(initialValue: current)
    }

    var body: some View {
        // rebuilt on *current* changed
        ContentInnerView(current: $current)
            .environmentObject(current)
    }

    struct ContentInnerView: View {
        @Binding var current: MyObject   // change current

        @EnvironmentObject var objects: MyObjects
        @EnvironmentObject var currentObject: MyObject

        init(current: Binding<MyObject>) {
            _current = current
        }

        var sceneDelegate: UISceneDelegate {
            guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                let sd = windowScene.delegate as? SceneDelegate else { fatalError() }
            return sd
        }

        var body: some View {
            VStack {
                Form {
                    Section(header: Text("Current Object")) {
                        Text(currentObject.id.uuidString)
                    }
                    Section(header: Text("Archived Objects")) {
                        List(objects.values, id: \.id) { object in
                            Text(object.id.uuidString)

                        }
                        Button(action: {
                            self.objects.values.append(self.currentObject)
                            self.current = MyObject() // << works !!
                        }) {
                            Text("Archive Object")
                        }
                    }
                }

                Spacer()
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61827121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档