[英]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.