使用Swift过滤UISearchBar的核心数据

时间:2014-12-10 16:18:15

标签: iphone swift core-data uisearchbar nsfetchedresultscontroller

我有一个UISearchBar,它连接到由Core Data填充的表视图。我在过滤工作方面遇到了很多麻烦。大多数关于此的教程都非常陈旧,并没有为我工作。我正在考虑将实体转换为数组并对数组进行过滤,但我已经读到了效率低下的问题。我想我应该使用NSPredicate,但老实说我不知道​​该怎么做。有任何想法吗?感谢。

2 个答案:

答案 0 :(得分:2)

我实际上一直在研究这个,我刚刚把它放在GitHub上。可以找到它here.就其实施而言,您必须为您的班级设置UITableViewControllerNSFetchedResultsControllerUISearchDisplayDelegate

class ContactsViewController: UITableViewController, NSFetchedResultsController, UISearchDisplayDelegate {
}

这样会有两个表视图:

  • 来自tableViewController(self.tableView)的tableView
  • 来自searchDisplayController的您的tableView(searchDisplayController?.searchResultsTableView

    您还为fetchedResultsControllersearchResultsControllerappDelegatemanagedObjectContext制作了类变量:

    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?
    }
    

    最后,您需要实施searchDisplayControllerWillUnloadSearchResultssearchDisplayControllerShouldReloadTableForSearchString

    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。