使用 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. 就其实现而言,您必须为您的班级设置UITableViewController
、NSFetchedResultsController
和UISearchDisplayDelegate
:
class ContactsViewController: UITableViewController, NSFetchedResultsController, UISearchDisplayDelegate
这样就会有两个表格视图:
来自 tableViewController 的 tableView (self.tableView
)
来自 searchDisplayController 的 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!
【讨论】:
重要提示:UISearchDisplayController 在 ios 8 中已弃用。(请注意,UISearchDisplayDelegate 也已弃用。)要在 iOS 8 及更高版本中管理搜索栏的呈现和显示搜索结果,请改用 UISearchController。跨度> 【参考方案2】:从 iOS 8 开始,不推荐使用 searchDisplayController。
【讨论】:
以上是关于使用 Swift 过滤 UISearchBar 的核心数据的主要内容,如果未能解决你的问题,请参考以下文章
UISearchbar 在 Swift 4 中使用 UItextfield
Swift 2.0 - UISearchBar 取消按钮不删除 searchBar 内容