为了简单起见,假设我要创建一个简单的待办事项应用程序。我的xcdatamodel中有一个实体Todo,其属性为id,title和date和以下swiftui视图(如图所示):
id
title
date
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> var dateFormatter: DateFormatter { let formatter = DateFormatter() formatter.dateStyle = .short return formatter } var body: some View { VStack { List { ForEach(todos, id: \.self) { todo in HStack { Text(todo.title ?? "") Text("\(todo.date ?? Date(), formatter: self.dateFormatter)") } } } Form { DatePicker(selection: $date, in: ...Date(), displayedComponents: .date) { Text("Datum") } } Button(action: { let newTodo = Todo(context: self.moc) newTodo.title = String(Int.random(in: 0 ..< 100)) newTodo.date = self.date newTodo.id = UUID() try? self.moc.save() }, label: { Text("Add new todo") }) } } }
待办事项在获取时按日期排序,并显示在这样的列表中:
我想基于每个待办事项各自的日期将列表分组(样机):
据我了解,这可以与该init()函数中的Dictionary一起使用,但是我无法提出任何对远程有用的东西。有一种有效的数据分组方法吗?
init()
您可以尝试以下操作,它应适合您的情况。
@Environment(\.managedObjectContext) var moc @State private var date = Date() @FetchRequest( entity: Todo.entity(), sortDescriptors: [ NSSortDescriptor(keyPath: \Todo.date, ascending: true) ] ) var todos: FetchedResults<Todo> var dateFormatter: DateFormatter { let formatter = DateFormatter() formatter.dateStyle = .short return formatter } 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 { 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) } Form { DatePicker(selection: $date, in: ...Date(), displayedComponents: .date) { Text("Datum") } } Button(action: { let newTodo = Todo(context: self.moc) newTodo.title = String(Int.random(in: 0 ..< 100)) newTodo.date = self.date newTodo.id = UUID() try? self.moc.save() }, label: { Text("Add new todo") }) } }