1

PHChangeイベントの発生後にデータ ソースを変更しようとすると問題が発生します。NSMutableOrderedSetデータ ソース タイプとしてを使用しています。が発生すると、 、、およびのPHChange3 つの可能なインデックスが返されます。removedIndexesinsertedIndexeschangedIndexes

問題は、これらの変更を以前のデータ ソースに反映する方法がわからないことです。で与えられたインデックスを変換してPHChange私のrecentsCollectionDataSource. 私UICollectionViewrecentsCollectionDataSourceそのデータソースとして使用します。

現在、唯一の方法は、変更されたインデックスを使用する代わりに、手動で列挙して独自の変更されたインデックスを作成することだと考えていPHFetchResultChangeDetailsます。

提供されたヘルプに感謝します。データ ソースを作成する別の方法についての推奨事項も歓迎します。

コード:

@property (nonatomic, strong) PHFetchResult *assetsFetchResult;
@property (nonatomic, strong) NSMutableOrderedSet *recentsCollectionDataSource;

- (void)setup
{
    self.recentsCollectionDataSource = [[NSMutableOrderedSet alloc]init];

    self.assetsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum | PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];

    for (PHAssetCollection *sub in self.assetsFetchResult)
    {
        PHFetchResult *assetsInCollection = [PHAsset fetchAssetsInAssetCollection:sub options:nil];

        for (PHAsset *asset in assetsInCollection)
        {
            [self.recentsCollectionDataSource addObject:asset];
        }
    }

    if (self.recentsCollectionDataSource.count > 0)
    {
        NSArray *array = [self.recentsCollectionDataSource sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]];

        self.recentsCollectionDataSource = [[NSMutableOrderedSet alloc]initWithArray:array];
    }
}

- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.assetsFetchResult];

    if (collectionChanges)
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
        {
            self.assetsFetchResult = [collectionChanges fetchResultAfterChanges];

            if (!collectionChanges.hasIncrementalChanges || collectionChanges.hasMoves)
            {
                dispatch_async(dispatch_get_main_queue(),^
                {
                    [self.recentsCollectionView reloadData];
                });
            }
            else
            {
                dispatch_async(dispatch_get_main_queue(),^
                {
                    [self.recentsCollectionView performBatchUpdates:^
                     {
                         NSIndexSet *removedIndexes = [collectionChanges removedIndexes];
                         NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes];
                         NSIndexSet *changedIndexes = [collectionChanges changedIndexes];

                         // Need to update our old recentsCollectionDataSource
                         // somehow, otherwise we get a crash.

                         if (removedIndexes.count)
                         {
                             [self.recentsCollectionView deleteItemsAtIndexPaths:[removedIndexes indexPathsFromIndexesWithSection:0]];
                         }

                         if (insertedIndexes.count)
                         {
                             [self.recentsCollectionView insertItemsAtIndexPaths:[insertedIndexes indexPathsFromIndexesWithSection:0]];
                         }

                         if (changedIndexes.count)
                         {
                             [self.recentsCollectionView reloadItemsAtIndexPaths:[changedIndexes indexPathsFromIndexesWithSection:0]];
                         }
                     }completion:NULL];
                });
            }
        });
    }
}

@implementation NSIndexSet (Convenience)

- (NSArray *)indexPathsFromIndexesWithSection:(NSUInteger)section
{
    NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:self.count];

    [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop)
    {
        [indexPaths addObject:[NSIndexPath indexPathForItem:idx inSection:section]];
    }];
    return indexPaths;
}

@end
4

1 に答える 1