我有一个UISearchBar,它连接到由Core Data填充的表视图。我在过滤工作方面遇到了很多麻烦。大多数关于此的教程都非常陈旧,并没有为我工作。我正在考虑将实体转换为数组并对数组进行过滤,但我已经读到了效率低下的问题。我想我应该使用NSPredicate,但老实说我不知道该怎么做。有任何想法吗?感谢。
答案 0 :(得分:2)
我实际上一直在研究这个,我刚刚把它放在GitHub上。可以找到它here.就其实施而言,您必须为您的班级设置UITableViewController
,NSFetchedResultsController
和UISearchDisplayDelegate
:
class ContactsViewController: UITableViewController, NSFetchedResultsController, UISearchDisplayDelegate {
}
这样会有两个表视图:
self.tableView
)的tableView
searchDisplayController?.searchResultsTableView
)
您还为fetchedResultsController
,searchResultsController
,appDelegate
和managedObjectContext
制作了类变量:
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
var managedObjectContext: NSManagedObjectContext? {
get {
if let delegate = appDelegate {
return delegate.managedObjectContext
}
return nil
}
}
var fetchedResultsController: NSFetchedResultsController?
var searchResultsController: NSFetchedResultsController?
在viewDidLoad()
中,您必须为searchResultsTableView
注册您的单元格,因为它在界面中不存在:
searchDisplayController?.searchResultsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "CellID")
您也可以在此设置fetchRequest:
fetchedResultsController = NSFetchedResultsController(fetchRequest: someFetchRequest, managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
您将需要一个函数,根据tableView返回您需要的FRC。您使此函数返回NSFetchedResultsController
,您将在所有表格视图函数中使用它,您可以从FRC中提取数据,例如cellForRowAtIndexPath:
,因为它将为您提供正确的数据集
func fetchedResultsControllerForTableView(tableView: UITableView) -> NSFetchedResultsController? {
return tableView == searchDisplayController?.searchResultsTableView ? searchResultsController? : fetchedResultsController?
}
最后,您需要实施searchDisplayControllerWillUnloadSearchResults
和searchDisplayControllerShouldReloadTableForSearchString
:
func searchDisplayController(controller: UISearchDisplayController, willUnloadSearchResultsTableView tableView: UITableView) {
searchResultsController?.delegate = nil
searchResultsController = nil
}
func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
let firstNamePredicate = NSPredicate(format: "nameFirst CONTAINS[cd] %@", searchString.lowercaseString)
let lastNamePredicate = NSPredicate(format: "nameLast CONTAINS[cd] %@", searchString.lowercaseString)
let predicate = NSCompoundPredicate.orPredicateWithSubpredicates([firstNamePredicate!, lastNamePredicate!])
searchResultsController = NSFetchedResultsController(fetchRequest: someOtherFetchRequestWithPredicate(predicate), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
searchResultsController?.performFetch(nil)
return true
}
如果您在填写其他内容时遇到任何问题,例如数据模型或NSFetchedResultsControllerDelegate方法,请查看demo!
答案 1 :(得分:2)
从iOS 8开始,不推荐使用searchDisplayController。