Обновление EnvironmentObject оттолкнуло меня
У меня есть два представления ListView и DetailView
Посмотреть список:
@EnvironmentObject var userData: UserData
var body: some View {
VStack {
ForEach(userData.packs) { pack in
if pack.added {
NavigationLink(destination: DetailView(packIndex: self.userData.packs.firstIndex(where: { $0.id == pack.id })!)) {
MyRowViewDoesntMatter(pack: pack)
}
}
}
}
.padding(.horizontal)
}
Подробный просмотр:
@EnvironmentObject var userData: UserData
var packIndex: Int
VStack {
List {
VStack {
.... some Vies ... doesn't matter
.navigationBarItems(trailing:
THE PROBLEM IS HERE (BELOW)
Button(action: {
self.userData.packs[self.packIndex].added.toggle()
}) {
Image(systemName: self.userData.packs[self.packIndex].added ? "plus.circle.fill" : "plus.circle")
}
...
Проблема в том, что я нажимаю кнопку в navigationBarItems в DetailView. Свойство "добавлено" объекта "@EnvironmentObject var userData: UserData" обновляется, и экран пользователя возвращается обратно (в RowView). Мне нравится, что проблема с EnvironmentObject, потому что данные обновляются, и View пытается повторно выполнить рендеринг (?), Поэтому он отталкивает меня?
Как это исправить? Я хочу остаться на экране DetailView после нажатия кнопки.
PS Мне нужно использовать тип EnvironmentObject, потому что тогда, когда я вернусь, мне нужно увидеть результаты.
Большое спасибо!
1 ответ
Возможный подход (путем введения какой-то выборки). В качествеNavigationView
не позволяет удалить ссылку из стека (как идентификатор стековой навигации), вероятно, также стоит рассмотреть отдельную модель представления для DetailView
для применения в общем контейнере после завершения редактирования.
Протестировано с Xcode 11.4 / iOS 13.4.
Некоторая репликация вашего кода, используемая для тестирования:
struct ListView: View {
@EnvironmentObject var userData: PushBackUserData
@State private var selectedPack: Pack? = nil
var body: some View {
NavigationView {
VStack {
ForEach(Array(userData.packs.enumerated()), id: \.element.id) { i, pack in
NavigationLink("Pack \(pack.id)", destination:
DetailView(pack: self.$selectedPack)
.onAppear {
self.selectedPack = pack
}
.onDisappear {
self.userData.packs[i].added = self.selectedPack?.added ?? false
}
).isHidden(!pack.added)
}
}
.padding(.horizontal)
}
}
}
struct DetailView: View {
@Binding var pack: Pack?
var body: some View {
VStack {
List {
VStack {
Text("Pack \(pack?.id ?? "<none>")")
}
}
.navigationBarItems(trailing:
Button(action: {
self.pack?.added.toggle()
}) {
Image(systemName: pack?.added ?? false ? "plus.circle.fill" : "plus.circle")
}
)
}
}
}
просто удобное вспомогательное расширение
extension View {
func isHidden(_ hidden: Bool) -> some View {
Group {
if hidden { self.hidden() }
else { self }
}
}
}