Смущает насчет @EnvironmentObject в SwiftUI - PullRequest
1 голос
/ 21 ноября 2019

Я пытаюсь применить @EnvironmentObject инструмент в SwiftUI.
объект общего доступа User init в ContentView.
Когда я переключаюсь с ContentView на NameView, они работают очень хорошо.
Но сNameView to AgeView не удалось. (посмотрите сообщение об ошибке и сеанс кода, пожалуйста)

Сообщение об ошибке

Fatal error: No ObservableObject of type User found.

Может кто-нибудь дать мне совет? Я что-то пропустил? thx

код

init "User" type in contentView
NavigationView

+-----------+                   +--------+                   +-------+
|ContentView+--NavigationLink-->|NameView+--NavigationLink-->|AgeView|
+-----------+                   +--------+                   +-------+
final class User: ObservableObject {
    @Published var name: String
    @Published var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

struct ContentView: View {
    var user: User = User(name: "SomeName", age: 44)
    var body: some View {
        NavigationView {
            VStack {
                Text("name: \(self.user.name) age: \(self.user.age)")
                NavigationLink(destination: NameView().environmentObject(self.user)) {
                    Text("Show Name")
                }
            }
        }
    }
}

struct NameView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("name: \(self.user.name)")
            NavigationLink(destination: AgeView()) {
                Text("Show Age")
            }
        }
    }
}

struct AgeView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("age: \(self.user.age)")
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 ноября 2019

Надеюсь, это поможет вам в следующем примере:

У нас есть наша модель, которая Наблюдаемая и имеет все ее переменные Опубликовано :

class A: ObservableObject {
    @Published var id: String = ""
    @Published var value: String = ""
}

При использовании его в качестве EnvironmentObject убедитесь, что вы установили это в SceneDelegate.swift следующим образом:

let example = Example()

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: example.environmentObject(A()))
        self.window = window
        window.makeKeyAndVisible()
    }

Тогда мы можем использовать это EnvironmentObject во всех представлениях:

struct Example: View {

    @EnvironmentObject var obj: A

    var body: some View {
        Button(action: {
            self.obj.value = "Hi im changed"
        }) {
            Text("Change me")
        }
    }
}

Иногда, когда вы хотите обновить данные в этом объекте, xCode может выдавать ошибку о 'EnvironmentObject не установлен для ... classnameи т. д. ', в этом случае вам нужно передать объект EnvironmentObject в представление назначения:

DestinationView().environmentObject(self.A)

Надеюсь, это поможет, удачи!

0 голосов
/ 21 ноября 2019

Вы назначаете EnvironmentObject в своем SceneDelegate для ContentView, поэтому все подпредставления ContentView автоматически могут получить доступ к вашему Пользователю.

Поэтому повторять его снова не нужно, как здесь: NameView().environmentObject(self.user)

Вам нужно только снова передать environmentObject, если вы показываете View внутри модификатора .sheet, потому что это в основном новое независимое представление.

final class User: ObservableObject {
    @Published var name: String
    @Published var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

struct ContentView: View {
    @EnvironmentObject var user: User
    var body: some View {
        NavigationView {
            VStack {
                Text("name: \(self.user.name) age: \(self.user.age)")
                NavigationLink(destination: NameView()) {
                    Text("Show Name")
                }
            }
        }
    }
}

struct NameView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("name: \(self.user.name)")
            NavigationLink(destination: AgeView()) {
                Text("Show Age")
            }
        }
    }
}

struct AgeView: View {
    @EnvironmentObject var user: User
    var body: some View {
        VStack {
            Text("age: \(self.user.age)")
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...