【问题标题】:Filtering Core Data for UISearchBar with Swift使用 Swift 过滤 UISearchBar 的核心数据
【发布时间】:2014-12-10 16:18:15
【问题描述】:

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

【问题讨论】:

  • 请发布相关代码,包括您的 NSFetchedResultsController 和 SearchBar 类

标签: iphone swift core-data uisearchbar nsfetchedresultscontroller


【解决方案1】:

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

class ContactsViewController: UITableViewController, NSFetchedResultsController, UISearchDisplayDelegate {
}

这样就会有两个表格视图:

  • 来自 tableViewController 的 tableView (self.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

  • 【讨论】:

    • 重要提示:UISearchDisplayController 在 iOS 8 中已弃用。(请注意,UISearchDisplayDelegate 也已弃用。)要在 iOS 8 及更高版本中管理搜索栏的呈现和显示搜索结果,请改用 UISearchController。跨度>
    【解决方案2】:

    从 iOS 8 开始,不推荐使用 searchDisplayController。

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多