重构为普通的UIViewController
与其让UITableView
在活动和非活动的UISearchController
之间切换,我将其重构为一个带有顶部UISearchBar
和直接位于其下方的UITableView
的普通UIViewController
。
我想做的是在fetchedResultsController
之间切换谓词,这个谓词由搜索栏中的文本设置,并且抓取所有内容。
我发现了这个答案,它描述了Objective-C中类似问题的解决方案,并成为我重构Swift项目的基础:
如何使用UISearchDisplayController / UISearchBar过滤NSFetchedResultsController(CoreData) https://dev59.com/wW855IYBdhLWcg3wNhd1#9512891
我的问题:如何为searchBar
文本更新我的fetchedResultsController?
tableView
正确地填充,但我无法弄清楚如何更新我的fetchedResultsController
以匹配我的searchPredicate
。这是我尝试过的方法。
以下是我在类顶部声明NSPredicate
和NSFetchedResultsController
的方式:
var searchPredicate = NSPredicate()
// Create fetchedResultsController to store search results
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Song")
let sortDescriptor = NSSortDescriptor(key: "songDescription", ascending: true);
// ** THESE TWO LINES CAUSE A CRASH, BUT NO COMPILER ERRORS **
// let predicate = self.searchPredicate
// fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
let frc = NSFetchedResultsController (fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: "songDescription", cacheName: nil)
frc.delegate = self
return frc
}()
这里是我的 UISearchBarDelegate
方法:
// MARK: - UISearchBarDelegate methods
// called when text changes (including clear)
internal func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText = \(searchBar.text)")
searchPredicate = NSPredicate(format: "(songDescription contains [cd] %@) || (songStar contains[cd] %@)", searchBar.text!, searchBar.text!)
// TODO: figure out how to update fetchedResultsController w/ predicate
}
// called when cancel button pressed
internal func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
searchBar.text = ""
// TODO: flip back to normal fetchResultsController
}
这里是我的
NSFetchedResultsControllerDelegate
方法。internal func controllerWillChangeContent(controller: NSFetchedResultsController) {
print("controllerWillChangeContent")
tableView.beginUpdates()
}
internal func controllerDidChangeContent(controller: NSFetchedResultsController) {
print("controllerDidChangeContent")
tableView.reloadData()
tableView.endUpdates()
}
internal func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Automatic)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic)
case .Update:
tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic)
case .Move:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic)
tableView.insertRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic)
}
}
感谢您的阅读。我欢迎您的建议。
fetchedResultsController.fetchRequest.predicate = NilLiteralConvertible
,而我想输入的是nil
!最后我输入了nil
,问题得以解决。 - Adrian