我有两个视图ListView和DetailView
ListView:
@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)
}
DetailView:
@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")
}
...
问题是当我单击DetailView的navigationBarItems中的按钮时。 “ @EnvironmentObject var userData:UserData”的“ added”属性将更新,并且用户的屏幕将返回(返回到RowView)。我发现EnvironmentObject存在问题,因为数据已更新并且View尝试重新渲染(?),这就是为什么它使我退缩了?
如何解决?单击按钮后,我想停留在DetailView屏幕上。
P.S。我需要使用EnvironmentObject类型,因为然后当我返回时,我需要查看结果。
非常感谢您!
答案 0 :(得分: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 }
}
}
}