代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

如何通过CoreData支持的NSFetchedResultsController更新UICollectionView的标头?

  •  0
  • Cheok Yan Cheng  · 技术社区  · 4 年前

    目前,我有以下基于CoreData的 NSFetchedResultsController

    我正在使用以下代码片段来更新 UICollectionView 的单元格内容。

    这是我更新UICollectionView单元格内容的方式

    // reloadItems and moveItem do not play well together. We are using the following workaround proposed at
    // https://developer.apple.com/videos/play/wwdc2018/225/
    
    extension BackupViewController: NSFetchedResultsControllerDelegate {
        func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
            if type == NSFetchedResultsChangeType.insert {
                blockOperations.append(
                    BlockOperation(block: { [weak self] in
                        if let self = self {
                            self.collectionView!.insertItems(at: [newIndexPath!])
                        }
                    })
                )
            }
            else if type == NSFetchedResultsChangeType.update {
                blockUpdateOperations.append(
                    BlockOperation(block: { [weak self] in
                        if let self = self, let indexPath = indexPath {
                            self.collectionView.reloadItems(at: [indexPath])
                        }
                    })
                )
            }
            else if type == NSFetchedResultsChangeType.move {
                blockOperations.append(
                    BlockOperation(block: { [weak self] in
                        if let self = self, let newIndexPath = newIndexPath, let indexPath = indexPath {
                            self.collectionView.moveItem(at: indexPath, to: newIndexPath)
                        }
                    })
                )
            }
            else if type == NSFetchedResultsChangeType.delete {
                blockOperations.append(
                    BlockOperation(block: { [weak self] in
                        if let self = self {
                            self.collectionView!.deleteItems(at: [indexPath!])
                        }
                    })
                )
            }
        }
    
        
        func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
            if blockOperations.isEmpty {
                performBatchUpdatesForUpdateOperations()
            } else {
                let completion: ((Bool) -> Void) = { [weak self] (finished) -> Void in
                    guard let self = self else { return }
                    
                    self.performBatchUpdatesForUpdateOperations()
                }
                
                collectionView.performBatchUpdates({ [weak self] () -> Void  in
                    guard let self = self else { return }
                    
                    for operation: BlockOperation in self.blockOperations {
                        operation.start()
                    }
                    
                    self.blockOperations.removeAll(keepingCapacity: false)
                    
                }, completion: completion)
            }
        }
        
        private func performBatchUpdatesForUpdateOperations() {
            if blockUpdateOperations.isEmpty {
                // TODO: Update top header. But how?
                
                return
            }
            
            collectionView.performBatchUpdates({ [weak self] () -> Void  in
                guard let self = self else { return }
                
                for operation: BlockOperation in self.blockUpdateOperations {
                    operation.start()
                }
                
                self.blockUpdateOperations.removeAll(keepingCapacity: false)
            }, completion: { [weak self] (finished) -> Void in
                guard let self = self else { return }
                
                // TODO: Update top header. But how?
            })
        }
    }
    

    在我更新了单元格内容之后,我也想更新顶部标题。

    我可以知道我怎样才能做到这一点吗?

    0 回复  |  直到 4 年前
        1
  •  0
  •   lazarevzubov    4 年前

    你的问题似乎与核心数据无关。如果我说得对,您只需要一种方法来获取对应于索引路径部分的标头。 This method 可以使用:

    // Any place, where you have your index path.
    let header = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader, 
                                                  at: indexPath)
    // Update header any way you like.
    

    例如:

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
                    didChange anObject: Any,
                    at indexPath: IndexPath?,
                    for type: NSFetchedResultsChangeType,
                    newIndexPath: IndexPath?) {
    
      switch type {
        case .insert:
          // Insert a cell to the index path.
        case .delete:
          // Delete the cell at the index path.
        case .move:
          // Move the cell at the index path to the new index path.
        case .update:
          // Update the cell at the index path.
    
          // Update your header.
          let header = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader,
                                                        at: indexPath)
          header.text = "Updated" // Or whatever.
      }
    }
    
    

    ( This question this also 可能也有帮助。)