0

次のコードは実行時エラーを生成します: @EnvironmentObject エラー: このビューの祖先として欠落している可能性があります。環境内の tState は @ObservedObject です。

struct TEditorView: View {
    @EnvironmentObject private var tState: TState
    
    @State var name = ""
    
    init() {
        self._name = State(initialValue: tState.name)
    }
 
    var body: some View {
        ...
    }
}

XCode 12.0.1 iOS 14

4

3 に答える 3

1

答えは、明らかに init() 関数で環境オブジェクトにアクセスできないということです。ただし、ObservedObject は可能です。だから私はこれにコードを変更し、それは動作します。簡単にするために、TState をどこからでもアクセスできるシングルトンに変更しました。これはおそらく、多くの状況で @EnvironmentObject の使用に取って代わる可能性があります。

struct TEditorView: View {
    @ObservedObject private var tState = TState.shared
    //@EnvironmentObject private var tState: TState
    
    @State var name = ""
    
    init() {
        self._name = State(initialValue: tState.name)
    }
 
    var body: some View {
        ...
    }
}

于 2020-10-22T00:40:12.650 に答える
0

は、ドキュメントに従って@State設定する必要がprivateあり、 でのみアクセスする必要がありますView body

https://developer.apple.com/documentation/swiftui/state

YourObservableObject@EnvironmentObjectを使用して設定する必要がありますContentView().environmentObject()

https://developer.apple.com/documentation/combine/observableobject https://developer.apple.com/documentation/swiftui/stateobject

以下はサンプルコードです

import SwiftUI
class SampleOO: ObservableObject {
    @Published var name: String = "init name"
}
//ParentView
struct OOSample: View {
    //The first version of an @EnvironmentObject is an @ObservedObject or @StateObject
    //https://developer.apple.com/tutorials/swiftui/handling-user-input
    @ObservedObject var sampleOO: SampleOO = SampleOO()
    var body: some View {
        VStack{
            Button("change-name", action: {
                self.sampleOO.name = "OOSample"
            })
        
        Text("OOSample = " + sampleOO.name)
        //Doing this should fix your error code with no other workarounds
        ChildEO().environmentObject(sampleOO)
        SimpleChild(name: sampleOO.name)
        }
    }
}
//Can Display and Change name
struct ChildEO: View {
    @EnvironmentObject var sampleOO: SampleOO
    var body: some View {
        VStack{
            //Can change name
            Button("ChildEO change-name", action: {
                self.sampleOO.name = "ChildEO"
            })
            Text("ChildEO = " + sampleOO.name)
        }
    }
}
//Can only display name
struct SimpleChild: View {
    var name: String
    var body: some View {
        VStack{
            //Cannot change name
            Button("SimpleChild - change-name", action: {
                print("Can't change name")
                //self.name = "SimpleChild"
            })
            Text("SimpleChild = " + name)
        }
    }
}

struct OOSample_Previews: PreviewProvider {
    static var previews: some View {
        OOSample()
    }
}
于 2020-10-22T12:36:00.153 に答える