响应PHPhotoLibraryChangeObserver事件后更新选定的collectionview索引

时间:2019-04-09 18:56:45

标签: ios swift uicollectionview photokit

我正在为我的收藏夹视图选择一项功能,该功能可以显示用户资料库中的照片。我跟踪数组中的选定indexPath,并希望更新它们,以防在选择单元格的中间发生照片库更改观察者事件。例如,如果用户选择了索引3和4,并且更改观察者事件从集合视图中删除了索引1和2,则所选索引应更改为1和2。

我正在尝试使用以下功能手动进行操作:

fileprivate func removeIndicesFromSelections(indicesToRemove:IndexSet){


        var itemToRemove: Int?

        for (_, removeableIndex) in indicesToRemove.map({$0}).enumerated() {

            itemToRemove = nil

            for (itemIndex,indexPath) in selectedIndices.enumerated() {

                //deduct 1 from indices after the deletion index
                if (indexPath.item > removeableIndex) && (indexPath.item > 0) {

                    selectedIndices[itemIndex] = IndexPath(item: indexPath.item - 1, section: 0)

                } else if indexPath.item == removeableIndex {

                    itemToRemove = itemIndex

                }
            }

            if let remove = itemToRemove {
                selectedIndices.remove(at: remove)
                disableDeleteButtonIfNeeded()
            }

        }


    }


fileprivate func moveSelectedIndicesAfterInsertion (insertedIndices:IndexSet){

    for (_, insertedIndex) in insertedIndices.map({$0}).enumerated() {

        for (itemIndex,indexPath) in selectedIndices.enumerated() {

            //add 1 to indices after the insertion index
            if (indexPath.item >= insertedIndex) {

                selectedIndices[itemIndex] = IndexPath(item: indexPath.item + 1, section: 0)

            }


        }

    }

}

但是,这些问题比我预期的要复杂得多,我一直在其中发现错误。有没有更好的方法来处理这种情况(例如任何内置的集合视图功能),或者我只需要想出自己的上述功能?

2 个答案:

答案 0 :(得分:0)

您走在正确的道路上,但是您应该存储对用户实际选择的对象的引用,而不是用户选择的位置(因为可以更改)。

在这种情况下,应保留对所选照片标识符的引用(请参阅docs),然后可以确定应选择哪个单元格/索引路径。您可以将选择数组与图像数据源进行比较,以确定最新索引路径是什么。

答案 1 :(得分:0)

Apple提供了一种解决方案。您可以找到更多信息in official documentation page

基本上,您希望采用PHPhotoLibraryChangeObserver并实现以下功能:

func photoLibraryDidChange(_ changeInstance: PHChange) {
    guard let collectionView = self.collectionView else { return }
    // Change notifications may be made on a background queue.
    // Re-dispatch to the main queue to update the UI.
    DispatchQueue.main.sync {
        // Check for changes to the displayed album itself
        // (its existence and metadata, not its member assets).
        if let albumChanges = changeInstance.changeDetails(for: assetCollection) {
            // Fetch the new album and update the UI accordingly.
            assetCollection = albumChanges.objectAfterChanges! as! PHAssetCollection
            navigationController?.navigationItem.title = assetCollection.localizedTitle
        }
        // Check for changes to the list of assets (insertions, deletions, moves, or updates).
        if let changes = changeInstance.changeDetails(for: fetchResult) {
            // Keep the new fetch result for future use.
            fetchResult = changes.fetchResultAfterChanges
            if changes.hasIncrementalChanges {
                // If there are incremental diffs, animate them in the collection view.
                collectionView.performBatchUpdates({
                    // For indexes to make sense, updates must be in this order:
                    // delete, insert, reload, move
                    if let removed = changes.removedIndexes where removed.count > 0 {
                        collectionView.deleteItems(at: removed.map { IndexPath(item: $0, section:0) })
                    }
                    if let inserted = changes.insertedIndexes where inserted.count > 0 {
                        collectionView.insertItems(at: inserted.map { IndexPath(item: $0, section:0) })
                    }
                    if let changed = changes.changedIndexes where changed.count > 0 {
                        collectionView.reloadItems(at: changed.map { IndexPath(item: $0, section:0) })
                    }
                    changes.enumerateMoves { fromIndex, toIndex in
                        collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
                                                to: IndexPath(item: toIndex, section: 0))
                    }
                })
            } else {
                // Reload the collection view if incremental diffs are not available.
                collectionView.reloadData()
            }
        }
    }
}