UISearchDisplayController animate reloadData

后端 未结 2 1520
不思量自难忘°
不思量自难忘° 2020-12-21 12:24

I\'ve been reading all the documentation about UISearchDisplayController and its delegate but I can\'t find any way to animate the table view when

2条回答
  •  一生所求
    2020-12-21 12:55

    I know this question is old, but I recently faced this and wanted a solution that would work regardless of how the NSFetchedResultsController was initialized. It's based on @martin-r's answer above.

    Here's the corresponding gist: https://gist.github.com/stephanecopin/4ad7ed723f9857d96a777d0e7b45d676

    import CoreData
    
    extension NSFetchedResultsController {
        var predicate: NSPredicate? {
            get {
                return self.fetchRequest.predicate
            }
            set {
                try! self.setPredicate(newValue)
            }
        }
    
        var sortDescriptors: [NSSortDescriptor]? {
            get {
                return self.fetchRequest.sortDescriptors
            }
            set {
                try! self.setSortDescriptors(newValue)
            }
        }
    
        func setPredicate(predicate: NSPredicate?) throws {
            try self.setPredicate(predicate, sortDescriptors: self.sortDescriptors)
        }
    
        func setSortDescriptors(sortDescriptors: [NSSortDescriptor]?) throws {
            try self.setPredicate(self.predicate, sortDescriptors: sortDescriptors)
        }
    
        func setPredicate(predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor]?) throws {
            func updateProperties() throws {
                if let cacheName = cacheName {
                    NSFetchedResultsController.deleteCacheWithName(cacheName)
                }
    
                self.fetchRequest.predicate = predicate
                self.fetchRequest.sortDescriptors = sortDescriptors
                try self.performFetch()
            }
    
            guard let delegate = self.delegate else {
                try updateProperties()
                return
            }
    
            let previousSections = self.sections ?? []
            let previousSectionsCount = previousSections.count
            var previousObjects = Set(self.fetchedObjects as? [NSManagedObject] ?? [])
            var previousIndexPaths: [NSManagedObject: NSIndexPath] = [:]
            previousObjects.forEach {
                previousIndexPaths[$0] = self.indexPathForObject($0)
            }
            try updateProperties()
            let newSections = self.sections ?? []
            let newSectionsCount = newSections.count
            var newObjects = Set(self.fetchedObjects as? [NSManagedObject] ?? [])
            var newIndexPaths: [NSManagedObject: NSIndexPath] = [:]
            newObjects.forEach {
                newIndexPaths[$0] = self.indexPathForObject($0)
            }
    
            let updatedObjects = newObjects.intersect(previousObjects)
            previousObjects.subtractInPlace(updatedObjects)
            newObjects.subtractInPlace(updatedObjects)
    
            var moves: [(object: NSManagedObject, fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath)] = []
            updatedObjects.forEach { updatedObject in
                if let previousIndexPath = previousIndexPaths[updatedObject],
                    let newIndexPath = newIndexPaths[updatedObject]
                {
                    if previousIndexPath != newIndexPath {
                        moves.append((updatedObject, previousIndexPath, newIndexPath))
                    }
                }
            }
    
            if moves.isEmpty && previousObjects.isEmpty && newObjects.isEmpty {
                // Nothing really changed
                return
            }
    
            delegate.controllerWillChangeContent?(self)
    
            moves.forEach {
                delegate.controller?(self, didChangeObject: $0.object, atIndexPath: $0.fromIndexPath, forChangeType: .Move, newIndexPath: $0.toIndexPath)
            }
    
            let sectionDifference = newSectionsCount - previousSectionsCount
            if sectionDifference < 0 {
                (newSectionsCount.. 0 {
                (previousSectionsCount..

    It exposes 2 properties on the NSFetchedResultsController, predicate and sortDescriptors which mirrors those found in the fetchRequest.
    When either of these properties are set, the controller will automatically compute changes the changes and send them through the delegate, so hopefully there is no major code changes. If you don't want animations, you can still directly set predicate or sortDescriptors on the fetchRequest itself.

提交回复
热议问题