【问题标题】:How do I use a Fetch Request for multiple entities in CoreData?如何对 CoreData 中的多个实体使用 Fetch Request?
【发布时间】:2022-01-24 19:12:35
【问题描述】:

目标:我想按我已经实现的截止日期显示Todo 项目的列表。但我还想在待办事项列表上方的同一视图中显示不同实体的列表Categories。类别是按钮,可将您带到过滤到该类别的待办事项列表。我将 Category 的关系设置为有很多待办事项。如何更改我的 FetchRequest 以支持添加的关系?

下面是当前的SectionedFetchRequest。如果我尝试为类别添加新的 FetchRequest,我会崩溃。

    @SectionedFetchRequest(entity: Todo.entity(),
                           sectionIdentifier: \.dueDateRelative,
                           sortDescriptors: [NSSortDescriptor(keyPath: \Todo.dueDate, ascending: true)],
                           predicate: nil,
                           animation: Animation.linear)
    var sections: SectionedFetchResults<String, Todo>
                    ForEach(sections) { section in
                        Section(header: Text(section.id.description)) {
                            ForEach(section) { todo in
                                TodoRowView(todo: todo)
                                    .frame(maxWidth: .infinity)
                                    .listRowSeparator(.hidden)
                            }
                            .onDelete { indexSet in
                                deleteTodo(section: Array(section), offsets: indexSet)
                            }
                        }
                    }
// Causes Crash when added to existing Fetch Request
//@FetchRequest(entity: Category.entity(), sortDescriptors: []) var categories: FetchedResults<Category>

【问题讨论】:

  • 你想用它做什么?显示在上面还是下面?您可以使用todo.relationship 访问Category。为什么需要第二个FetchRequest?您的问题/目标不清楚。
  • 我想在待办事项列表上方为不同的Categories 添加部分。点击该类别将打开一个新列表,该列表中只有 Todos。 (“收件箱、工作、个人”)他们可以从表单中选择一个类别来添加待办事项。 @loremipsum

标签: ios swift xcode core-data swiftui


【解决方案1】:

你可能想多了。如果您为该类别添加sectionIdentifier,您可以相对容易地提供选项。

变量看起来像这样

extension Todo{
    @objc
    var categoryTitle: String{
        self.relationship?.title ?? "no category"
    }
}

然后在View中添加几个变量

//Dictionary to store sort options
let sortOptions: [String: KeyPath<Todo, String>] = ["due date": \Todo.dueDateRelative, "category":\Todo.categoryTitle]
//Variable to use to filter list
@State var selectedSection: String = ""
//filter the `sections` by the selected section
//You can use nsPredicate too
var filteredSections: [SectionedFetchResults<String, Todo>.Element] {
    sections.filter({ val in
        if !selectedSection.isEmpty {
            return val.id == selectedSection
        }else{
            return true
        }
    })
}

然后给用户一些按钮来选择

//Give the user sort options
Menu("sort"){
    ForEach(Array(sortOptions.keys).sorted(by: <), id:\.self, content: { key in
        Button(key, action: {
            sections.sectionIdentifier = sortOptions[key]!
            selectedSection = ""
        })
    })
}
//Give the user section options
Picker("sections", selection: $selectedSection, content: {
    ForEach(sections, content: {section in
        Text(section.id).tag(section.id)
    })
    Text("all").tag("")
}).pickerStyle(.segmented)

ForEach 会自动显示用户选择

ForEach(filteredSections) { section in

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多