我一直在try 构建的SwiftUI应用程序的排序和分组过程.
我看到的所有教程在排序和过滤方面都相当"基础",特别是在使用SwiftData时.
我想要整合的不仅是按其中一个属性和正向/反向排序,而且还将数据分组.
例如,这是Apple的Earthquake项目的代码(为了简洁起见,删除了一些项目):
struct QuakeList: View {
@Environment(ViewModel.self) private var viewModel
@Environment(\.modelContext) private var modelContext
@Query private var quakes: [Quake]
init(
sortParameter: SortParameter = .time,
sortOrder: SortOrder = .reverse
) {
switch sortParameter {
case .time:
_quakes = Query(sort: \.time, order: sortOrder)
case .magnitude:
_quakes = Query(sort: \.magnitude, order: sortOrder)
}
}
他们在这里所做的是将sortParameter
和sortOrder
传递给这个视图,并在更改/更新时重新呈现视图.
我如何扩展它,使它也可以处理分组,使quakes
变量实际上是一个多维数组,甚至是一个字典.
例如,我试图这样做来执行渲染:
enum GroupOption { // New grouping for Section
case time
case magnitude
case none
}
struct ListScreen: View {
@Environment(ViewModel.self) private var viewModel
@Environment(\.modelContext) private var modelContext
@Query private var quakes: [Quake]
@State private var groupedQuakes: [[Quake]] = [] // New multidimensional array
init(
sortParameter: SortParameter = .time,
sortOrder: ComparisonResult = .orderedAscending, // using ComparisonResult to store the enum value in defaults
sortGrouping: GroupOption = .none
) {
switch (sortParameter, sortOrder) {
case (.time, .orderedAscending):
_quakes = Query(sort: \.time, order: .forward)
case (.time, .orderedDescending):
_quakes = Query(sort: \.time, order: .reverse)
case (.magnitude, .orderedAscending):
_quakes = Query(sort: \.magnitude, order: .forward)
case (.magnitude, .orderedDescending):
_quakes = Query(sort: \.magnitude, order: .reverse)
default:
_quakes = Query(sort: \.time, order: .forward)
}
switch sortGrouping {
case .time:
groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.time })
.sorted(by: { $0.key < $1.key })
.map({ $0.value })
case .magnitude:
groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.magnitude })
.sorted(by: { $0.key < $1.key })
.map({ $0.value })
case .none:
groupedQuakes = [_quakes.wrappedValue]
}
}
但是,当我在视图主体中使用它时,它是空的.因此,从// 1
切换到// 2
会使数据数组返回空.
// 1
List(quakes) { quake in
QuakeRow(quake: quake)
}
// 2
List {
ForEach(groupedQuakes, id: \.self) { group in
Section {
ForEach(group) { quake in
QuakeRow(quake: quake)
}
} header: {
groupHeader(for: group)
}
}
}
// ...
func groupHeader(for group: [Quake]) -> Text {
guard let group = group.first else { return Text("Unknown") }
switch groupOption {
case .time:
return Text(group.time.formatted(date: .numeric, time: .omitted))
case .magnitude:
return Text("\(group.magnitude)")
case .none:
return Text("All quakes")
}
}
因此,当我返回一般@Query private var quakes: [Quake]
时,有一个数组返回数据.
使用Apple测试项目中包含的排序,quakes
个被正确排序.
一旦我try 添加分组和排序,数据返回空array.
我是不是忽略了什么?