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(例如范围按钮),请在谓词中添加其他术语。