如何使用SwiftUI和CoreData(@FetchRequest)动态列表排序



我有一个显示CoreData FetchRequest的列表,还有一个改变列表排序方式的Picker。我目前实现这一点的方式如下:

struct ParentView: View {
enum SortMethod: String, CaseIterable, Identifiable {
var id: Self { self }

case byName = "Name"
case byDateAdded = "Date Added"
}
@State private var currentSortMethod = SortMethod.byName
var body: some View {
ItemListView(sortMethod: currentSortMethod) // See child view implementation below
.toolbar {
ToolbarItem(placement: .principal) {
Picker("Sort by", selection: $currentSortMethod) {
ForEach(SortMethod.allCases) { sortMethod in
Text(sortMethod.rawValue)
}
}
}
}
}
}

子视图看起来像:

struct ItemListView: View {

@Environment(.managedObjectContext) private var managedObjectContext
@FetchRequest var items: FetchedResults<Item>

init(sortMethod: ParentView.SortMethod) {
let sortDescriptor: NSSortDescriptor
switch sortMethod {
case .byName:
sortDescriptor = NSSortDescriptor(keyPath: Item.name, ascending: true)
case .byDateAdded:
sortDescriptor = NSSortDescriptor(keyPath: Item.dateAdded, ascending: true)
}
_items = .init(
entity: Item.entity(),
sortDescriptors: [sortDescriptor],
predicate: nil,
animation: .default
)
}

var body: some View {
List {
ForEach(items) { item in
SingleItemView(item)
}
}
}
}

但是,当我更改排序选项时,该列表不会为重新排序设置动画(可能是由于整个ItemListView正在重建。如果我在父视图中将.animation(.default)添加到ItemListView(),则列表在重新排序时会显示动画,但在从其他视图导航回来时也会显示奇怪的动画。我似乎不知道在哪里可以添加withAnimation { }块。或者有没有更好的方法可以让SwiftUI更自然,从而允许一些默认动画?

绑定可以附加动画,所以请尝试以下操作(或使用您想要的任何动画参数(

Picker("Sort by", selection: $currentSortMethod.animation())  // << here !!

最新更新