我正在创建一个应用程序来记录费用。我在白天做了一个SectionedFetchRequest。但这里我有一个问题:
每个部分的顺序似乎不正确。它将费用从最旧的部分排列到新的部分,而理想的情况是相反的。请参阅图像以获得更好的澄清。
显示错误顺序的图像:
如图所示,顺序为:
1,2,3,4当它应该是4,3,2,1从上到下。
如果我在SectionedFetchRequest中将升序部分更改为“true”,那么每个部分的顺序都是正确的,但整个列表的顺序是错误的(最早的费用首先显示,应该是相反的顺序)。
验证码:
struct LogListView: View {
@Environment(\.managedObjectContext) var moc
@SectionedFetchRequest(entity: ExpenseLog.entity(), sectionIdentifier: \.date, sortDescriptors: [NSSortDescriptor(keyPath: \ExpenseLog.date, ascending: false)]) var logs: SectionedFetchResults<Date?, ExpenseLog>
@State var logToEdit: ExpenseLog?
@State var searchText = ""
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .short
return formatter
}
var body: some View {
List {
ForEach((logs), id: \.id) { section in
Section(header: Text(dateFormatter.string(from: section[0].date!))) {
ForEach(section.filter({
self.searchText.isEmpty ? true :
$0.name!.localizedStandardContains(self.searchText)
})) { log in
Button {
logToEdit = log
} label: {
HStack(spacing: 16) {
CategoryIconsView(category: log.categoryEnum)
VStack(alignment: .leading, spacing: 8) {
Text(log.nameText).font(.subheadline)
}
Spacer()
Text(log.typeTransaction != "expensive" ? log.amountText : "-\(log.amountText)").font(.subheadline).foregroundColor(log.typeTransaction == "income" ? .green : .primary)
}
.padding(.vertical, 4)
}
.swipeActions(content: {
Button(role: .destructive, action: {
deleteTodo(log: log)
}, label: {
Image(systemName: "trash")
})
})
}
}
}
}
.listStyle(.plain)
.searchable(text: $searchText)
.sheet(item: $logToEdit, onDismiss: {
self.logToEdit = nil
}) { (log: ExpenseLog) in
AddLogView(name: log.name ?? "", amount: log.amount , category: Category(rawValue: log.category ?? "") ?? .food, date: log.date ?? Date(), logToEdit: log)
}
}
}
有什么办法解决这个问题吗?谢谢!
1条答案
按热度按时间nmpmafwu1#
您可能只是看到了错误的部分名称,请尝试:
(FYI你必须将
dateFormatter
移到结构体的外部,这样它才是全局的。在View
结构体内部多次初始化对象被认为是内存泄漏)我注意到你是按日期划分的,所以你可能只想根据日期而不是时间来划分。
然后你可以做
sectionIdentifier: \.dayDate
。我也注意到你的搜索不太对,应该是这样的:
所以现在你可以有正确的
ForEach(section) { log in
而不是手动过滤。请注意,目前
@FetchRequest
中有一个主要缺陷,即如果父视图重新初始化LogListView
,则其 predicate 丢失,因此您必须考虑到这一点,例如将其 Package 在永不更改的子视图中。你可能还想动态地改变排序顺序,为此我建议观看Bring Core Data concurrency to Swift and SwiftUI from WWDC 2021,但他的一些SwiftUI代码很糟糕,例如自定义的
Binding
而不是像我上面那样使用onChange
。如果你使用开发者应用程序观看,你可以轻松地复制代码。