0
votes

Erreur SWIFTUI @EnvironmentObject: Peut être manquante comme un ancêtre de cette vue - Accéder à l'objet dans l'init ()

Le code suivant produit l'erreur d'exécution: @environmentObject Erreur: Peut être manquant comme un ancêtre de cette vue. Le TSTE dans l'environnement est un @OBServedObject.

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


0 commentaires

3 Réponses :


0
votes

La réponse est qu'un objet d'environnement n'est apparemment pas accessible dans une fonction init (). Cependant, une observation objecte peut être. J'ai donc changé le code et cela fonctionne. Pour faciliter la tâche, j'ai tourné Tstate dans un singleton que je pouvais accéder n'importe où. Cela pourrait probablement remplacer l'utilisation de @environmentObject dans de nombreuses situations.

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 {
        ...
    }
}


1 commentaires

Dans iOS 14, vous pouvez également utiliser «@stateObject» à la place de '@observedObject'. La clé ici est vraiment que vous accédez à l'objet Tstate comme un singleton au lieu de via '@environmentObject'. Les autres réponses ne semblent pas résoudre le problème: lorsque vous devez accéder à l'objet à init ().



0
votes

Une approche différente ici pourrait être d'injecter la valeur initiale ttstate dans le constructeur et en faire avec le @environmentObject complètement. Ensuite, à partir de la vue du parent, vous pouvez utiliser la valeur @environmentObject lors de la création de la vue. xxx

ou utilisez un @binding au lieu de < code> @state si le nom la valeur est destiné à être bidirectionnel.

En général, je me pose également de question pourquoi vous avez besoin du @environmentObject dans le constructeur. L'idée est avec un @environmentObject est qu'il est représenté le même dans toutes les vues, vous ne devez donc en avoir besoin que corps .

Si vous avez besoin de Transformations de données Il devrait être effectué dans le modèle d'objet lui-même, pas la vue.


0 commentaires