Ich habe eine NSFetchedResultsController
Anzeige einiger Daten aus Core Data und ich versuche, eine Suchleiste damit arbeiten zu bekommen. Die Suche funktioniert, aber controller(didChangeObject:)
wird mit Indexpfaden von der vollständigen Tabelle aufgerufen, nicht von der gefilterten, sodass das Aktualisieren entweder den falschen Datensatz oder Fehler ändert, da der Indexpfad außerhalb des Bereichs liegt. Obwohl ich weiß, dass dies die Ursache des Fehlers ist, weiß ich nicht, wie ich das beheben soll. Die wesentlichen Teile meines Codes sind wie folgt:Wie kann ich NSFetchedResultsController Update mit einem UISearchController arbeiten lassen?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PlayerTableViewCell", forIndexPath: indexPath) as! PlayerTableViewCell
let coreDataIndexPath: NSIndexPath
if searchController.active && searchController.searchBar.text != "" {
coreDataIndexPath = fetchedResultsController.indexPathForObject(filteredPlayers[indexPath.row])!
} else {
coreDataIndexPath = indexPath
}
configureCell(cell, atIndexPath: coreDataIndexPath)
return cell
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Fetch Record
let record = fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
// Delete Record
managedObjectContext.deleteObject(record)
}
}
// MARK: Fetched Results Controller Delegate Methods
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch (type) {
case .Insert:
if let indexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
case .Update:
if let indexPath = indexPath {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! PlayerTableViewCell
configureCell(cell, atIndexPath: indexPath)
}
case .Move:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
if let newIndexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
}
}
// MARK: UISearchResultsUpdating
func updateSearchResultsForSearchController(searchController: UISearchController) {
if let searchText = searchController.searchBar.text {
let predicate = NSPredicate(format: "name CONTAINS %@", searchText)
if let fetchedObjects = fetchedResultsController.fetchedObjects as? [Player] {
filteredPlayers = fetchedObjects.filter({return predicate.evaluateWithObject($0)})
}
}
tableView.reloadData()
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.active && searchController.searchBar.text != "" {
return filteredPlayers.count
} else if let sections = fetchedResultsController.sections {
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
return 0
}
configureCell
lädt nur die Daten aus dem Datensatz bei indexPath in die Zelle.
Ich hatte zuvor versucht, die Suche zu tun, indem ich die fetchedResultsController.fetchRequest.predicate
änderte, aber die Tabelle würde nicht zu normal zurückkehren, wenn die Suchleiste abgebrochen wurde, trotz meiner besten Bemühungen. Dieser Code war wie folgt:
// MARK: UISearchResultsUpdating
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchText = searchController.searchBar.text!
let predicate = NSPredicate(format: "%K CONTAINS[c] %@", argumentArray: ["name", searchText])
fetchedResultsController.fetchRequest.predicate = predicate
do {
try self.fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("\(fetchError), \(fetchError.userInfo)")
}
tableView.reloadData()
}
// MARK: UISearchBarDelegate
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
fetchedResultsController.fetchRequest.predicate = nil
do {
try self.fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("\(fetchError), \(fetchError.userInfo)")
}
tableView.reloadData()
}
Haben Sie jemals herausgefunden? Ich habe die gleichen Probleme. – NRitH