在我的应用程序中,我需要在轻按按钮时重新实例化@EnvironmentObject
。正确的位置在哪里?
这是我的视图的屏幕截图-在“存档的对象”列表中,我想拥有不可变的对象。因此,当我点击Archive Object
时,我想将当前对象添加到数组中并创建一个新的当前对象。
该应用程序的简化版本如下所示。
我在SceneDelegate
中实例化该对象:
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()
}
}
//.....
}
这是我的模特:
class MyObject: ObservableObject, Identifiable {
@Published var id = UUID()
}
class MyObjects: ObservableObject {
@Published var values: [MyObject] = [
MyObject(),
MyObject()
]
}
在我看来,我需要将当前对象放入一个(归档)数组,然后创建一个新的当前对象来使用。这是我正在尝试的:
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()
}
}
}
答案 0 :(得分:0)
这是一个解决方案。查看内嵌评论。
通过Xcode 11.4 / iOS 13.4测试
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()
}
}
}
}