我在 iOS 16 上的 SwiftUI 中发现了一些奇怪的错误。
我正在使用 CoreData 作为数据库。 我有带有项目列表的主屏幕和带有操作的工具栏菜单。
我可以在那里切换到列表的编辑模式。当我打开它时,列表会重新呈现并显示用于移动行的正确附件。
我在推送表单屏幕上向数据库添加新项目。我返回列表。我看到上面添加了新项目。我尝试切换到编辑模式,但“什么都没有”发生。
[
EditMode 已打开,但未使用正确的附件重新渲染单元格。
在我添加新项目之前它工作正常。
经过一些强制重新渲染,比如从数据库中删除项目,编辑模式下的附件正确显示。
看起来 List 在后台重新渲染会产生奇怪的 List 行为。
我在 iOS 15.6 模拟器上试过了,它运行正常。
哪里会出问题?
伪代码:
列表
struct ListView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Item.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Item.id, ascending: true)
]
) var items: FetchedResults<Item>
@State var editMode = EditMode.inactive
@State var goNewItem = false
var body: some View {
NavigationView {
GeometryReader { frame in
ZStack {
List {
ForEach(items, id: \.self) { item in
// Render cell
}
}
Button {
goNewItem.toggle()
} label: {
ZStack {
Image("add")
.resizable()
.frame(width: 20, height: 20)
.padding(20)
}
.background(Color.primaryColor)
.cornerRadius(30)
.shadow(radius: 4)
}
.position(x: frame.size.width - 50, y: frame.size.height-50)
.buttonStyle(PlainButtonStyle())
.foregroundColor(.secondaryTextColor)
NavigationLink(destination: ItemDetailView(), isActive: $goNewItem) {
EmptyView()
}
.hidden()
}
.listStyle(.plain)
.padding(.top, 10)
.environment(\.editMode, $editMode)
Spacer()
}
}
}
}
添加项目
struct ItemDetailView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.presentationMode) var presentationMode
@State private var note: String = ""
var body: some View {
Form {
VStack(spacing: 20) {
// inputs
TextArea("Note", text: $note)
.frame(minHeight: 30)
Button {
save()
} label: {
Text(Strings.shortcut_button_save.uppercased())
.padding(4)
.frame(maxWidth: .infinity)
}
.padding(.bottom, 20)
}
}
.listStyle(GroupedListStyle())
}
private func save() {
withAnimation {
do {
let item = Item(context: viewContext)
item.note = note
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
}