Refactored ванили UIViewController
Обновления fetchedResultsController для предиката, установленного UISearchBar
Вместо того, чтобы иметь в UITableView
переключении между активным и неактивным UISearchController
, я переработан к ванили UIViewController
с UISearchBar
в верхнем и UITableView
непосредственно под ним ,
То, что я пытаюсь сделать, это переключить fetchedResultsController
между наличием предиката, который задается текстом в searchBar, и тем, который захватывает все.
Я нашел ответ, который описывает решение аналогичной задачи в 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)
}
}
Спасибо, что прочитали. Я приветствую ваши предложения.
Благодарим за то, что вышли на финишную прямую! Я понял метод поиска из этого сообщения http://stackoverflow.com/a/32073151/4475605, но отмена поиска меня отбрасывала с автозаполнения b/c, предлагая 'fetchedResultsController.fetchRequest.predicate = NilLiteralConvertible', когда я был пытаясь напечатать 'nil'! Я набрал нуль, и это позаботилось обо всем остальном. – Adrian