【发布时间】:2026-01-22 21:45:01
【问题描述】:
我在 iOS 应用中拥有的是:
TO DO ITEMS
To do item 3
24/03/2020
------------
To do item 2
24/03/2020
------------
To do item 1
23/03/2020
------------
我想要的是:
TO DO ITEMS
24/03
To do item 3
24/03/2020
------------
To do item 2
24/03/2020
------------
23/03
To do item 1
23/03/2020
------------
================
我目前所拥有的:
我正在使用 Core Data 并且有 1 个实体:Todo。模块:当前产品模块。 Codegen:类定义。 该实体有2个属性:标题(字符串)、日期(日期)。
ContentView.swift 显示列表。
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@State private var date = Date()
@FetchRequest(
entity: Todo.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Todo.date, ascending: true)
]
) var todos: FetchedResults<Todo>
@State private var show_modal: Bool = false
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .short
return formatter
}
// func to group items per date. Seemed to work at first, but crashes the app if I try to add new items using .sheet
func update(_ result : FetchedResults<Todo>)-> [[Todo]]{
return Dictionary(grouping: result){ (element : Todo) in
dateFormatter.string(from: element.date!)
}.values.map{$0}
}
var body: some View {
NavigationView {
VStack {
List {
ForEach(update(todos), id: \.self) { (section: [Todo]) in
Section(header: Text( self.dateFormatter.string(from: section[0].date!))) {
ForEach(section, id: \.self) { todo in
HStack {
Text(todo.title ?? "")
Text("\(todo.date ?? Date(), formatter: self.dateFormatter)")
}
}
}
}.id(todos.count)
// With this loop there is no crash, but it doesn't group items
//ForEach(Array(todos.enumerated()), id: \.element) {(i, todo) in
// HStack {
// Text(todo.title ?? "")
// Text("\(todo.date ?? Date(), formatter: self.dateFormatter)")
// }
//}
}
}
.navigationBarTitle(Text("To do items"))
.navigationBarItems(
trailing:
Button(action: {
self.show_modal = true
}) {
Text("Add")
}.sheet(isPresented: self.$show_modal) {
TodoAddView().environment(\.managedObjectContext, self.moc)
}
)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return ContentView().environment(\.managedObjectContext, context)
}
}
TodoAddView.swift 在此视图中,我添加了新项目。
import SwiftUI
struct TodoAddView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.managedObjectContext) var moc
static let dateFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter
}()
@State private var showDatePicker = false
@State private var title = ""
@State private var date : Date = Date()
var body: some View {
NavigationView {
VStack {
HStack {
Button(action: {
self.showDatePicker.toggle()
}) {
Text("\(date, formatter: Self.dateFormat)")
}
Spacer()
}
if self.showDatePicker {
DatePicker(
selection: $date,
displayedComponents: .date,
label: { Text("Date") }
)
.labelsHidden()
}
TextField("title", text: $title)
Spacer()
}
.padding()
.navigationBarTitle(Text("Add to do item"))
.navigationBarItems(
leading:
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Cancel")
},
trailing:
Button(action: {
let todo = Todo(context: self.moc)
todo.date = self.date
todo.title = self.title
do {
try self.moc.save()
}catch{
print(error)
}
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
}
)
}
}
}
struct TodoAddView_Previews: PreviewProvider {
static var previews: some View {
TodoAddView()
}
}
我试过这个: 我已经搜索了一些例子。一个看起来不错:How to properly group a list fetched from CoreData by date? 我从那里使用了更新功能和 ForEach,但它不适用于 SwiftUI 中的 .sheet 。当我打开 .sheet(点击添加后)时,应用程序崩溃并出现错误:
线程 1:异常:“尝试为单元格创建两个动画”
如何解决?还是有另一种按日期对核心数据进行分组的方法?有人告诉我应该将分组添加到我的数据模型中。稍后在 UI 中显示。我不知道从哪里开始。
另一个猜测是我也许可以编辑我的@FetchRequest 代码以在那里添加分组。但我正在寻找几天没有运气的解决方案。 我知道 Core Data 中有一个 setPropertiesToGroupBy,但我不知道它是否以及如何与 @FetchRequest 和 SwiftUI 一起使用。
另一个猜测: 是否可以使用 Dictionary(grouping: attributeName) 根据属性在 SwiftUI 中对 CoreData Entity 实例进行分组? 分组数组看起来很简单:https://www.hackingwithswift.com/example-code/language/how-to-group-arrays-using-dictionaries,但我不知道它是否以及如何与 Core Data 和 @FetchRequest 一起使用。
【问题讨论】:
-
如果你想分组,那么你需要使用我认为的列表,否则你将不得不手动进行。
-
谢谢。我认为 List 是个好主意。但是如何从核心数据中获取项目,对它们进行分组并在每个组中按 id 排序?我被告知要在数据模型中进行分组。但这我真的不知道如何开始:/
-
在您的示例中,您按日期分组,如果这是您想要的,那么链接的答案应该会有所帮助。您还在问题中提到了类别,如果这是您想要的,那么您应该为它添加一个具有一对多关系的核心数据模型的实体,以便项目可以有一个类别。
-
这个链接的答案不适用于 SwiftUI .sheet。它使应用程序崩溃。现在让我们忘记预定义的类别。我想要的最低要求是按日期分组
-
老实说,我不明白 .sheet 与它有什么关系,那不只是一种窗口吗?你不能在工作表中有一个列表还是有什么问题?链接的答案是使用 SwiftUI,因此您的声明一定是错误的。
标签: ios swift core-data swiftui categories