NSFetchedResultsContollerDelegate for CollectionView

前端 未结 6 1082
悲哀的现实
悲哀的现实 2020-11-30 21:10

I\'d like to use the NSFetchedResultsControllerRelegate in a CollectionViewController. Therefore I just changed the method for the TableViewController for the CollectionView

6条回答
  •  盖世英雄少女心
    2020-11-30 21:32

    Here is my implementation with Swift. First initialise an array of NSBlockOperations:

    var blockOperations: [NSBlockOperation] = []
    

    In controller will change, re-init the array:

    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        blockOperations.removeAll(keepCapacity: false)
    }
    

    In the did change object method:

        func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    
        if type == NSFetchedResultsChangeType.Insert {
            println("Insert Object: \(newIndexPath)")
    
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.insertItemsAtIndexPaths([newIndexPath!])
                    }
                })
            )
        }
        else if type == NSFetchedResultsChangeType.Update {
            println("Update Object: \(indexPath)")
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.reloadItemsAtIndexPaths([indexPath!])
                    }
                })
            )
        }
        else if type == NSFetchedResultsChangeType.Move {
            println("Move Object: \(indexPath)")
    
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.moveItemAtIndexPath(indexPath!, toIndexPath: newIndexPath!)
                    }
                })
            )
        }
        else if type == NSFetchedResultsChangeType.Delete {
            println("Delete Object: \(indexPath)")
    
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.deleteItemsAtIndexPaths([indexPath!])
                    }
                })
            )
        }
    }
    

    In the did change section method:

    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    
        if type == NSFetchedResultsChangeType.Insert {
            println("Insert Section: \(sectionIndex)")
    
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.insertSections(NSIndexSet(index: sectionIndex))
                    }
                })
            )
        }
        else if type == NSFetchedResultsChangeType.Update {
            println("Update Section: \(sectionIndex)")
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.reloadSections(NSIndexSet(index: sectionIndex))
                    }
                })
            )
        }
        else if type == NSFetchedResultsChangeType.Delete {
            println("Delete Section: \(sectionIndex)")
    
            blockOperations.append(
                NSBlockOperation(block: { [weak self] in
                    if let this = self {
                        this.collectionView!.deleteSections(NSIndexSet(index: sectionIndex))
                    }
                })
            )
        }
    }
    

    And finally, in the did controller did change content method:

    func controllerDidChangeContent(controller: NSFetchedResultsController) {        
        collectionView!.performBatchUpdates({ () -> Void in
            for operation: NSBlockOperation in self.blockOperations {
                operation.start()
            }
        }, completion: { (finished) -> Void in
            self.blockOperations.removeAll(keepCapacity: false)
        })
    }
    

    I personally added some code in the deinit method as well, in order to cancel the operations when the ViewController is about to get deallocated:

    deinit {
        // Cancel all block operations when VC deallocates
        for operation: NSBlockOperation in blockOperations {
            operation.cancel()
        }
    
        blockOperations.removeAll(keepCapacity: false)
    }
    

提交回复
热议问题