Удаление из отфильтрованных результатов поиска UISearchController

у меня естьtableView источник его содержимого клетки изCoreData и заменялиSearchDisplayController (не рекомендуется) с новымSearchController, Я использую то же самоеtableView контроллер для представления как полного списка объектов, так и отфильтрованных / найденных объектов.

Мне удалось настроить работу поиска / фильтрации, и я могу перейти от отфильтрованного списка к подробным представлениям этих элементов, а затем отредактировать и успешно сохранить изменения в отфильтрованном табличном представлении. Моя проблема смахивания для удаления ячеек из отфильтрованного списка вызывает ошибку во время выполнения. Ранее сSearchDisplayController Я мог бы сделать это легко, так как у меня был доступ кSearchDisplayController's Результаты TableView и так следующий (псевдо) код будет работать нормально:

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    // If the search is active do this
          searchDisplayController!.searchResultsTableView.endUpdates()
    // else it isn't active so do this
          tableView.endUpdates()
    }
}

К сожалению, нет такого tableView дляUISearchController и я в растерянности Я пытался сделатьtableView.beginUpdates() а такжеtableView.endUpdates() условно, что tableView не является поиском tableView, но безуспешно.

Для записи это мое сообщение об ошибке:

Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.65/UITableView.m:1582

* РЕДАКТИРОВАТЬ *

Мой tableView использует FetchedResultsController для заполнения себя из CoreData. Этот tableViewController также тот, который используется SearchController для отображения отфильтрованных результатов.

var searchController: UISearchController!

Тогда в ViewDidLoad

searchController = UISearchController(searchResultsController: nil)
searchController.dimsBackgroundDuringPresentation = false
searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = searchController?.searchBar
self.tableView.delegate = self
self.definesPresentationContext = true

а также

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = self.searchController?.searchBar.text
    if let searchText = searchText {
        searchPredicate = searchText.isEmpty ? nil : NSPredicate(format: "locationName contains[c] %@", searchText)
        self.tableView.reloadData()
    }
}

Что касается сообщения об ошибке, я не уверен, сколько я могу добавить. Приложение зависает сразу после нажатия красной кнопки удаления (которая продолжает отображаться), показанной при смахивании. Это журнал ошибок потока для 1 - 5. Приложение, кажется, висит на номер 4.

#0  0x00000001042fab8a in objc_exception_throw ()
#1  0x000000010204b9da in +[NSException raise:format:arguments:] ()
#2  0x00000001027b14cf in -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] ()
#3  0x000000010311169a in -[UITableView _endCellAnimationsWithContext:] ()
#4  0x00000001019b16f3 in iLocations.LocationViewController.controllerDidChangeContent (iLocations.LocationViewController)(ObjectiveC.NSFetchedResultsController) -> () at /Users/neilmckay/Dropbox/Programming/My Projects/iLocations/iLocations/LocationViewController.swift:303
#5  0x00000001019b178a in @objc iLocations.LocationViewController.controllerDidChangeContent (iLocations.LocationViewController)(ObjectiveC.NSFetchedResultsController) -> () ()

Я надеюсь, что это поможет.

* РЕДАКТИРОВАТЬ 2 *

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        let location: Location = self.fetchedResultsController.objectAtIndexPath(indexPath) as Location
        location.removePhotoFile()

        let context = self.fetchedResultsController.managedObjectContext
        context.deleteObject(location)

        var error: NSError? = nil
        if !context.save(&error) {
            abort()
        }
    }
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if self.searchPredicate == nil {
        let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
        return sectionInfo.numberOfObjects
    } else {
        let filteredObjects = self.fetchedResultsController.fetchedObjects?.filter() {
            return self.searchPredicate!.evaluateWithObject($0)
        }
        return filteredObjects == nil ? 0 : filteredObjects!.count
    }
}

// MARK: - NSFetchedResultsController methods

var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {
        return _fetchedResultsController!
    }

    let fetchRequest = NSFetchRequest()
    // Edit the entity name as appropriate.
    let entity = NSEntityDescription.entityForName("Location", inManagedObjectContext: self.managedObjectContext!)
    fetchRequest.entity = entity

    // Set the batch size to a suitable number.
    fetchRequest.fetchBatchSize = 20

    // Edit the sort key as appropriate.
    if sectionNameKeyPathString1 != nil {
        let sortDescriptor1 = NSSortDescriptor(key: sectionNameKeyPathString1!, ascending: true)
        let sortDescriptor2 = NSSortDescriptor(key: sectionNameKeyPathString2!, ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2]
    } else {
        let sortDescriptor = NSSortDescriptor(key: "firstLetter", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]
    }

    var sectionNameKeyPath: String
    if sectionNameKeyPathString1 == nil {
        sectionNameKeyPath = "firstLetter"
    } else {
        sectionNameKeyPath = sectionNameKeyPathString1!
    }

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: sectionNameKeyPath, cacheName: nil /*"Locations"*/)
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    var error: NSError? = nil
    if !_fetchedResultsController!.performFetch(&error) {
        fatalCoreDataError(error)
    }

    return _fetchedResultsController!
}

var _fetchedResultsController: NSFetchedResultsController? = nil

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    if searchPredicate == nil {
        tableView.beginUpdates()
    } else {
        (searchController.searchResultsUpdater as LocationViewController).tableView.beginUpdates()
    }

// tableView.beginUpdates ()}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    var tableView = UITableView()
    if searchPredicate == nil {
        tableView = self.tableView
    } else {
        tableView = (searchController.searchResultsUpdater as LocationViewController).tableView
    }

    switch type {
    case .Insert:
        tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    case .Delete:
        tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
    default:
        return
    }
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath) {
    var tableView = UITableView()
    if searchPredicate == nil {
        tableView = self.tableView
    } else {
        tableView = (searchController.searchResultsUpdater as LocationViewController).tableView
    }

    switch type {
    case .Insert:
        println("*** NSFetchedResultsChangeInsert (object)")
        tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)

    case .Delete:
        println("*** NSFetchedResultsChangeDelete (object)")
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    case .Update:
        println("*** NSFetchedResultsChangeUpdate (object)")
        if searchPredicate == nil {
            let cell = tableView.cellForRowAtIndexPath(indexPath) as LocationCell
            let location = controller.objectAtIndexPath(indexPath) as Location
            cell.configureForLocation(location)
        } else {
            let cell = tableView.cellForRowAtIndexPath(searchIndexPath) as LocationCell
            let location = controller.objectAtIndexPath(searchIndexPath) as Location
            cell.configureForLocation(location)
        }
    case .Move:
        println("*** NSFetchedResultsChangeMove (object)")
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
    }
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    if searchPredicate == nil {
        tableView.endUpdates()
    } else {
        (searchController.searchResultsUpdater as LocationViewController).tableView.endUpdates()
    }
}

Ответы на вопрос(1)

Ваш ответ на вопрос