#swift #swiftui #swiftui-environment
Вопрос:
Я пытаюсь передать некоторые данные между родственными представлениями.
У меня есть VerseDetailView
кнопка с кнопкой:
@StateObject var favoritesViewModel = FavoritesViewModel()
...
Button("Add to favorite") {
favoritesViewModel.add(verse: verse)
}
Моя FavoritesViewModel
внешность выглядит так:
class FavoritesViewModel: ObservableObject {
@Published var favoriteVerses: [Verse] = []
func add(verse: Verse) {
favoriteVerses.append(verse)
}
}
Как бы я перешел favoriteVerses
к отображению в совершенно другом подвиде?
Мой основной файл приложения выглядит так:
var body: some Scene {
WindowGroup {
TabView {
NavigationView {
BookView() // VerseDetailView is a child of this view
}
.tabItem {
Image(systemName: "book")
Text("Books")
}
NavigationView {
FavoritesView() // I want to get the array of favoriteVerses here
}
.tabItem {
Image(systemName: "bookmark")
Text("Favorites")
}
}
}
}
Моя FavoritesView
внешность выглядит так:
struct FavoritesView: View {
@EnvironmentObject var favoritesViewModel: FavoritesViewModel
// is this correct?
// I get a hread 1: "Fatal error: No ObservableObject of type FavoritesViewModel found" error
var body: some View {
List {
Section(header: Text("Favorite verses")) {
ForEach(favoritesViewModel.favoriteVerses) { verse in
Text(verse.verse)
}
}
}
}
}
Я попытался добавить это в верхней части основного файла приложения:
var favoritesViewModel = FavoritesViewModel()
...
NavigationView {
FavoritesView().environmentObject(favoritesViewModel)
}
Но это тоже не работает
Ответ №1:
Добавьте его для общего вида сверху (в вашем случае это так TabView
), например
TabView {
NavigationView {
BookView() // VerseDetailView is a child of this view
}
.tabItem {
Image(systemName: "book")
Text("Books")
}
NavigationView {
FavoritesView() // I want to get the array of favoriteVerses here
}
.tabItem {
Image(systemName: "bookmark")
Text("Favorites")
}
}
.environmentObject(favoritesViewModel) // << here !!
Комментарии:
1. По-прежнему ничего.. когда я перехожу на другую вкладку, она полностью пуста.
var favoritesViewModel = FavoritesViewModel()
Все еще должен быть наверху? Может ли это быть что-то с повторным уничтожением представления, поэтому список стихов не отображается? С другой стороны, я больше не получаю фатальной ошибки, но список все еще пуст2. это звучит как другая проблема — как будто вы создаете разные модели в разных представлениях
3. Должен ли я по-прежнему иметь
@StateObject var favoritesViewModel = FavoritesViewModel()
в своемVerseDetailView
и в сцене делегатаvar favoritesViewModel = FavoritesViewModel()
?4. Нет, вам нужно создать только один делегат сцены — во всех остальных местах доступ к нему через
@EnvironmentObject
оболочку.
Ответ №2:
Вы можете передать объект environmentObject в каждое представление следующим образом:
TabView {
NavigationView {
BookView() // VerseDetailView is a child of this view
}
.tabItem {
Image(systemName: "book")
Text("Books")
}
.environmentObject(favoritesViewModel)
NavigationView {
FavoritesView() // I want to get the array of favoriteVerses here
}
.tabItem {
Image(systemName: "bookmark")
Text("Favorites")
}
.environmentObject(favoritesViewModel)
}