Рефакторинг изменен на ванильный UIViewController
Вместо того, чтобы UITableView
переключаться между активным и неактивным UISearchController
, я провел рефакторинг в ванильный UIViewController
с UISearchBar
вверху и UITableView
прямо под ним.
То, что я пытаюсь сделать, это переключить fetchedResultsController
между наличием предиката, который устанавливается текстом в строке поиска, и предикатом, который захватывает все.
Я нашел этот ответ, который описывает решение аналогичной проблемы в Objective-C и послужил основой для рефакторинга моего проекта Swift:
Как отфильтровать NSFetchedResultsController (CoreData) с помощью UISearchDisplayController/UISearchBar https://stackoverflow.com/a/9512891/4475605
Моя проблема: как обновить fetchedResultsController для текста searchBar
?
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)
}
}
Спасибо за чтение. Я приветствую ваши предложения.