使用 Swift 过滤 UISearchBar 的核心数据

Posted

技术标签:

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

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

【问题讨论】:

请发布相关代码,包括您的 NSFetchedResultsController 和 SearchBar 类 【参考方案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。

【讨论】:

以上是关于使用 Swift 过滤 UISearchBar 的核心数据的主要内容,如果未能解决你的问题,请参考以下文章

UISearchbar 在 Swift 4 中使用 UItextfield

未在自定义 UISearchBar 中获取过滤器数据

Swift 2.0 - UISearchBar 取消按钮不删除 searchBar 内容

UISearchbar 并在查看控制器 xcode swift 中传递数据

使用 UISearchBar 过滤数组

通过 UISearchBar 使用 CoreData 过滤查询