SwiftUI 中如何动态创建和过滤 FetchRequest
发布
更新
字数
341
阅读
2 分钟
阅读量
1125
在 SwiftUI 中使用 Core Data,可以使用 property wrapper @FetchRequest
声明一个 FetchedResults
属性,自动从 Core Data 存储中获取一个数据集。参考文档:https://developer.apple.com/documentation/swiftui/fetchrequest
Fetch request 需要使用环境变量 .managedObjectContext
获取 Core Data 的 managed object context,通常在上一层视图注入:
ContentView()
.environment(
\.managedObjectContext,
PersistenceController.shared.container.viewContext)
然后创建一个 fetch request
@FetchRequest(sortDescriptors: [SortDescriptor(\.time, order: .reverse)])
private var quakes: FetchedResults<Quake> // Quake 是 Core Data model
如何动态创建 FetchRequest
?
有时我们需要动态调整 fetch request 的 sortDescriptor
或者 nsPredicate
属性,实现排序、过滤、搜索等功能。
在初始化时创建 fetch request
// ...
@FetchRequest var fetchRequest: FetchedResults<Singer>
init(filter: String) {
_fetchRequest = FetchRequest<Singer>(sortDescriptors: [], predicate: NSPredicate(format: "lastName BEGINSWITH %@", filter))
}
参考:https://www.hackingwithswift.com/books/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui
动态修改 fetch request
通过 FetchedResults
实例的 nsPredicate
和 sortDescriptors
可以直接修改 fetch request 配置。
// ...
@State private var query = ""
// ...
.onChange(of: query) { value in
quakes.nsPredicate = query.isEmpty
? nil
: NSPredicate(format: "place CONTAINS %@", value)
}
与输入框绑定
如果我们需要根据一个输入框的输入内容过滤列表,例如自动完成的候选项,我们可以自定义绑定:
// @FetchRequest ...
// private var options ...
@State private input: String = ""
private var name: Binding<String> {
get { input }
set { newValue in
input = bindingInput
if newValue.isEmpty {
options.nsPredicate = nil
return
}
options.nsPredicate = NSPredicate(format: "name contains[cd] %@", newValue)
}
}
//
TextFiled("Name", text: $name)