我正在开发一个应用程序,当从详细信息视图中删除列表中的最后一项时,遇到了List和NavigationLink的奇怪行为。我使用的是iOS 13和Xcode 11,我制作了一个简化的版本来重现此行为:
import SwiftUI
struct ListView: View {
@State private var content = [Int](0..<10) {
didSet {
print(content)
}
}
var body: some View {
NavigationView {
List(content, id: \.self) { element in
NavigationLink(
destination: DetailView(
remove: {
DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1) { // Asynchronous network request
DispatchQueue.main.async {
self.content.removeAll { $0 == element } // When request was successfull remove element from list
}
}
}
)
) {
Text("Element #\(element)")
}
}
}
}
}
struct DetailView: View {
let remove: () -> Void
init(remove: @escaping () -> Void) {
self.remove = remove
}
var body: some View {
VStack {
Text("Hello world!")
Button(
action: {
self.remove()
}
) {
Image(systemName: "trash.circle")
.imageScale(.large)
}
}
}
}
要重建错误,请选择列表中的最后一项,然后按垃圾桶将其删除。您可能会注意到,该视图并没有像列表中的其他项一样消失。但是,如果您按回去,该列表将正确删除最后一项。此gif中也显示了这一点。按下垃圾桶时,列表的状态更改会打印到控制台上。
我注意到删除特定项目似乎不是问题,因为删除随机项目时也会发生。如果我删除所选项目并在末尾添加新项目,则它可以正常工作。因此,这可能是由于缩小数组大小引起的。
我还找到了几种解决方法。就像使用.id(UUID())修改NavigationView一样,但这会删除动画。另一种解决方案是使用PresentationMode关闭视图,然后消失,从列表中删除该项目,但我宁愿使用其他解决方案。
要查看它是否与iOS 13或Xcode 11相关,我在最新的beta版本的iOS 14和Xcode 12(当前为beta 5)上对其进行了测试。在这里,详细信息视图不会与任何选定项一起消失。
有人有没有遇到过这个问题,或者至少可以解释为什么会这样?
编辑:添加了模拟网络请求以更好地说明特定问题。
答案 0 :(得分:0)
SwiftUI在那儿表现得有些奇怪,我想...
您可以明确地告诉SwiftUI关闭DetailView。为此,您需要对DetailView进行一些修改:
struct DetailView: View {
@Environment(\.presentationMode) var presentationMode
let remove: () -> Void
init(remove: @escaping () -> Void) {
self.remove = remove
}
var body: some View {
VStack {
Text("Hello world!")
Button(
action: {
self.remove()
self.presentationMode.wrappedValue.dismiss()
}
) {
Image(systemName: "trash.circle")
.imageScale(.large)
}
}
}
}
(另请参见:iOS SwiftUI: pop or dismiss view programmatically)
对我来说,即使是最后一行,这似乎也可行。