[英]Can't Update Text on Previous View using @EnvironmentObject SwiftUI
[英]Can @EnvironmentObject be used with a plain struct that isn't a View?
我在将类信息从一个结构实例传递到另一个实例时遇到了麻烦,所以我一直在尝试解决问题。
这是有效的,因为我正在通过视图
// phone_testingApp.swift
import SwiftUI
@main
struct phone_testingApp: App {
@ObservedObject var myObservedObject = MyObservedObject()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(myObservedObject)
}
}
}
// ContentView.swift
import SwiftUI
import Combine
struct ContentView: View {
var subtract = MinusToObject()
@EnvironmentObject var myNumber: MyObservedObject
var body: some View {
VStack{
Text("The number is \(myNumber.theObservedObjectToPass)")
MinusToObject()
.environmentObject(myNumber)
}
}
}
class MyObservedObject: ObservableObject {
@Published var theObservedObjectToPass = 5
}
struct MinusToObject: View {
@EnvironmentObject var theObservedObject: MyObservedObject
var body: some View {
Text("Minus")
.onTapGesture {
theObservedObject.theObservedObjectToPass -= 1
}
}
}
但如果我尝试类似的东西,只是一个不符合 View 这样的普通结构
import SwiftUI
import Combine
struct ContentView: View {
var subtract = MinusToObject()
@EnvironmentObject var myNumber: MyObservedObject
var body: some View {
VStack{
Text("The number is \(myNumber.theObservedObjectToPass)")
Text("Minus")
.onTapGesture {
subtract.subtractIt()
}
}
}
}
class MyObservedObject: ObservableObject {
@Published var theObservedObjectToPass = 5
}
struct MinusToObject {
@EnvironmentObject var theObservedObject: MyObservedObject
func subtractIt() {
theObservedObject.theObservedObjectToPass -= 1 //Thread 1: Fatal error: No ObservableObject of type MyObservedObject found. A View.environmentObject(_:) for MyObservedObject may be missing as an ancestor of this view.
}
}
我收到一个运行时错误,这是我在函数调用时注释的。
我对如何传递引用类型的实例感到非常困惑,所以我确定我做错了很多事情,任何帮助将不胜感激。
这是行不通的,因为EnvironmentObject
注入仅在 SwiftUI View
层次结构上执行到所有基于子视图的对象。
如果您希望任何旧对象访问共享实例,则必须手动创建一个单例并将其注入 SwiftUI 视图层次结构中。
class MyObservedObject: ObservableObject {
static let shared = MyObservedObject()
private init() { }
@Published var theObservedObjectToPass = 5
}
/// you can use it in a plain object
struct MinusToObject {
func subtractIt() {
MyObservedObject.shared.theObservedObjectToPass -= 1
}
}
// you can use it in a view
struct ContentView: View {
var body: some View {
SomeOtherView()
.environmentObject(MyObservedObject.shared)
}
}
@ObservedObject var myObservedObject = MyObservedObject()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(myObservedObject)
}
}
这足以让您在 ContentView 的任何其他子视图中获得相同的myObservedObject
实例作为environmentObject
。 唯一的例外是.sheet
,您需要通过使用相同的.environmentObject(envObjInstance)
修饰符为sheet
内的视图手动为每个 sheet .environmentObject(envObjInstance)
修饰符。
对于不符合视图的结构,您可以将环境对象实例的包装值传递给它们,对此传递的实例的任何更改也将反映在您的视图中。
如何:
为您的结构声明一个变量:
struct AnyStruct {
var anEnvironmentObject: EnvironmentObject<TheEnvironmentObjectType>.Wrapper
.
.
.
}
然后在 SwiftUI 视图中,首先初始化您的结构:
struct someSwiftUIView: View {
@EnvironmentObject var myEnvObj: TheEnvironmentObjectType
var anyStruct: AnyStruct { AnyStruct.init(anEnvironmentObject: $myEnvObject) }
// notice the dollar sign `$`
}
然后在您的AnyStruct
,您可以更改 environmentObject 中的值,并确保它们也将反映在您的视图中。 您只需要记住,您需要使用.wrappedValue
为环境对象内的变量分配一个新值。 假设您的 environmentObject 中有一个名为observedInteger
的变量:
extension AnyStruct {
func changeValueOfObservedIntegerToZero() {
self.anEnvironmentObject.observedInteger.wrappedValue = 0
// notice the `.wrappedValue`
}
}
请注意,这种方法 100% 对我有用,但我不确定是否可以更简单。 您甚至可能不需要将环境对象的包装值传递给结构体,您可以只传递简单值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.