Swift使用NSFetchedResultsController和UISearchBarDelegate

我正在寻找一个解决这个问题的好方法。 我想在我拥有的TableView上实现一些简单的搜索function。

我找到的所有示例都使用不推荐使用的UISearchDisplayController或使用新的UISearchController但没有NSFetchedResultsController目前使用Core Data / NSFetchedResultsController填充

到目前为止,我已经设法让它达到我可以收集用户的搜索字符串的点(喔!)。 我知道我可能需要一个单独的FRC来执行搜索,但如上所述,到目前为止所有尝试都失败了。

我的class级符合以下协议:

 class JobListController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UISearchBarDelegate{ 

我不能使用UITableViewController因为我已经编写了大量现有function,依赖于这个类是UIViewController我有两个IBOutlets

 @IBOutlet var tblJobs : UITableView! @IBOutlet weak var searchBar: UISearchBar! 

和我的空数组来保存我的各种Core Data位和bob:

 var workItems = [Work]() var filteredWorkItems = [Work]() 

这是我如何初始化我的FRC ,以及我的MOC ,我已经离开了我空的第二个FRC因为我很确定在某些时候需要它:

  let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext lazy var fetchedResultsController: NSFetchedResultsController = { let workFetchRequest = NSFetchRequest(entityName: "Work") let primarySortDescriptor = NSSortDescriptor(key: "createdDate", ascending: true) let secondarySortDescriptor = NSSortDescriptor(key: "town", ascending: true) workFetchRequest.sortDescriptors = [primarySortDescriptor, secondarySortDescriptor] let frc = NSFetchedResultsController( fetchRequest: workFetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: "createdDate", cacheName: nil) frc.delegate = self return frc }() var searchResultsController: NSFetchedResultsController? 

在我的viewDidLoad函数中,我正在为我的表和searchBar设置委托/数据源:

  tblJobs.delegate = self tblJobs.dataSource = self searchBar.delegate = self 

这是searchBar函数,这是我所处的位置。 stringMatch变量是先前尝试的剩余,我希望能够在这里搜索大量不同的参数,但是如果我只能使用一个,那么它将是一个可靠的开始。

 func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { println("Search text is \(searchText)") self.filteredWorkItems = self.workItems.filter({( work: Work) -> Bool in // let stringMatch = work.postcode.rangeOfString(searchText) return stringMatch != nil }) if(filteredWorkItems.count == 0){ searchActive = false; } else { searchActive = true; } self.tblJobs.reloadData() } 

这是我的cellForRowAtIndexPath函数,用于显示我如何从fetchedResultsController提取数据

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ let cell = self.tblJobs.dequeueReusableCellWithIdentifier( "JobCell", forIndexPath: indexPath) as! JobTableViewCell let workItem = fetchedResultsController.objectAtIndexPath(indexPath) as! Work //... return cell } 

所以你可以看到我在这里发生了一些事情,最终我想知道如何使用我新获得的searchText字符串来查询我的FRC ,然后在View中正确过滤结果。

更新:

我试图将搜索字符串添加到FRC NSPredicate ,如下所示:

 lazy var fetchedResultsController: NSFetchedResultsController = { ../ workFetchRequest.predicate = NSPredicate(format:"title contains[cd] %@", savedSearchTerm!) //... return frc }() 

导致'JobListController.Type' does not have a member named 'savedSearchTerm'结果'JobListController.Type' does not have a member named 'savedSearchTerm'

在我的class级的顶部,我已经设置了这样:

 var savedSearchTerm: NSString? 

所以不确定我做错了什么?

从您的代码中,我假设您要使用相同的表视图来显示结果。 因此,您只需使用基于搜索词的新filter更新FRC。

将搜索词存储在变量中。 在FRC工厂函数中,包含谓词,如下所示:

 request.predicate = searchText?.characters.count > 0 ? NSPredicate(format:"title contains[cd] %@", searchText!) : nil 

文本更改时,重置FRC并重新加载。

 fetchedResultsController = nil tableView.reloadData() 

如果您有其他filter(例如范围按钮),请在谓词中添加其他术语。