我正在开发一个从CoreData检索数据的应用程序。我从数据库中检索出一个项目列表,并将它们显示在屏幕上。
用户可以选择在5个单独的下拉菜单中为多达5个类别过滤这些项目。动态执行此操作的最佳方法是什么?我的意思是,如果用户选择一个过滤器选项,则仅显示与该过滤器匹配的项目,以及其他过滤器选项,然后仅显示已经过滤的项目存在的过滤器选项。
我希望这是有道理的!
这是我目前用于检索项目的代码:
func showDropDown(filterButton: UIButton) -> Void {
selectedButton = filterButton
let popController = UIStoryboard(name: STORYBOARD_NAME,
bundle: nil).instantiateViewController(withIdentifier: STORYBOARD_ID) as! FilterDropDownViewController
popController.modalPresentationStyle = .popover
popController.delegate = self
popController.popoverPresentationController?.permittedArrowDirections = .up
popController.popoverPresentationController?.delegate = self
popController.popoverPresentationController?.sourceView = filterButton
popController.popoverPresentationController?.sourceRect = filterButton.bounds
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
var predicate = NSPredicate(format: "code matches[c] '\(code!)'")
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = predicate
let entity = NSEntityDescription.entity(forEntityName: "Item",
in: context)
fetchRequest.resultType = .dictionaryResultType
let entityProperties = entity?.propertiesByName
let filterToFetch = "filter\(filterButton.tag)"
let propertiesToFetch: [Any] = [entityProperties![filterToFetch]!]
fetchRequest.propertiesToFetch = propertiesToFetch
fetchRequest.returnsDistinctResults = true
var result = [[String : String]]()
do {
result = try context.fetch(fetchRequest) as! [[String : String]]
} catch {
print("Unable to fetch managed objects for Item).")
}
var filterArray = [Filter]()
for dict in result {
if let search = dict[filterToFetch] {
predicate = NSPredicate(format: "code matches[c] '\(search)'")
let filterCode = DatabaseHelper.fetchRecordsForEntity(entity: "Filter",
managedObjectContext: context,
predicate: predicate) as! [Filter]
filterArray.append(filterCode.first!)
}
}
popController.filterArray = filterArray
present(popController, animated: true, completion: nil)
}
答案 0 :(得分:1)
您可以通过以下简单步骤进行操作:
NSFetchResultsController
),使用适当的谓词创建一个NSCompoundPredicate
,然后进行提取。将视图控制器设置为委托,并在数据更改时重新加载collectionView的数据(似乎您不希望用户在查看数据时更改数据,因此可以保持简单)。更新NSFetchResultsController时,请不要忘记重新加载collectionView。fetchedObjects
,并查看它具有哪些可过滤的属性。将这些属性添加到一组(每个过滤器类别一个)。然后查看集合以确定要显示和更新UI的过滤器。NSFetchResultsController
的委托设置为nil,然后再创建新的代理,并按照步骤1中的说明创建新的代理。在您共享的代码中,您无需进行复杂的提取就可以确定哪些过滤器是相关的。我不知道您的代码是否正确,但是我知道它很复杂。而且,只需在fetchResultsController中查看您已经可以访问的managedObject中的属性,速度就会更快。这些项目已经被获取并存储在内存中,因此不需要再次访问数据库。与用代码过滤这些项目相比,弄清楚如何编写一个复杂的谓词要容易得多。