iOS PHPhotoLibrary 资源增删改

/ 0评 / 0

PHAsset PHAssetCollection PHCollectionList对象都是不可变的。那么我们如何实现资源增删改呢?要借助 request API :

比如:这段代码用來修改一张图片的资源属性:是否被收藏。

// 创建
request = [PHAssetChangeRequest creationRequestForAssetFromImage:image]

- (void)toggleFavoriteForAsset:(PHAsset *)asset {
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        // 改变
        PHAssetChangeRequest *request = [PHAssetChangeRequest changeRequestForAsset:asset];
        request.favorite = !asset.favorite;
          } completionHandler:^(BOOL success, NSError *error) {
        NSLog(@"Finished updating asset. %@", (success ? @"Success." : error));
    }];
}

(1)创建PHAssetChangeRequest对象。想要修改资源,需要创建一个 PHAssetChangeRequest 。然后你就可以修改创建日期,资源位置,以及是否将资源隐藏,是否将资源看做用户收藏等。此外,你还可以从用户的库里删除资源。类似地,若要修改资源集合或集合列表,需要创建一个 PHAssetCollectionChangeRequest 或 PHCollectionListChangeRequest对象。然后你就可以修改集合标题,添加或删除集合成员,或者完全删除集合。
(2)操作的请求都要求在PHPhotoLibrary的performChanges的changeBlock中执行
(3)如果有更新UI操作,需要遵守PHPhotoLibraryChangeObserver协议,实现photoLibraryDidChange(changeInfo: PHChange!)方法.在photoLibraryDidChange中进行UI更新操作

// 为image对象生成PHAsset对象,并加入collection
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
    if (self.assetCollection) {
        PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.assetCollection];
        [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]];
    }
} completionHandler:^(BOOL success, NSError *error) {
    if (!success) {
        NSLog(@"Error creating asset: %@", error);
    }
}];

创建一个新资源只要用 creationRequestForAssetFromXXX(…)方法,来创建变化请求,并传入一个图像数据 (或一个 URL)。如果你需要对新建的资源做额外的修改,你可以用创建变化请求的placeholderForCreatedAsset属性。它会返回一个可用的 placeholder 來代替“真实的” PHAsset 引用.

// PHPhotoLibraryChangeObserver协议的方法,更新相册UI
- (void)photoLibraryDidChange:(PHChange *)changeInstance {
    // Check if there are changes to the assets we are showing.
    PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.assetsFetchResults];
    if (collectionChanges == nil) {
        return;
    }

    /*
        Change notifications may be made on a background queue. Re-dispatch to the
        main queue before acting on the change as we'll be updating the UI.
     */
    dispatch_async(dispatch_get_main_queue(), ^{
        // Get the new fetch result.
        self.assetsFetchResults = [collectionChanges fetchResultAfterChanges];

        UICollectionView *collectionView = self.collectionView;

        if (![collectionChanges hasIncrementalChanges] || [collectionChanges hasMoves]) {
            // Reload the collection view if the incremental diffs are not available
            [collectionView reloadData];

        } else {
            /*
                Tell the collection view to animate insertions and deletions if we
                have incremental diffs.
             */
            [collectionView performBatchUpdates:^{
                NSIndexSet *removedIndexes = [collectionChanges removedIndexes];
                if ([removedIndexes count] > 0) {
                    [collectionView deleteItemsAtIndexPaths:[removedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }

                NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes];
                if ([insertedIndexes count] > 0) {
                    [collectionView insertItemsAtIndexPaths:[insertedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }

                NSIndexSet *changedIndexes = [collectionChanges changedIndexes];
                if ([changedIndexes count] > 0) {
                    [collectionView reloadItemsAtIndexPaths:[changedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }
            } completion:NULL];
        }

        [self resetCachedAssets];
    });
}

当然你也可以不使用上面的方法,可以直接获取到操作的结果进行UI更新,就像我这里的需求,删除一个资源,并直接更新UI

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest deleteAssets:@[cellModel.asset]];
} completionHandler:^(BOOL success, NSError *error) {
    dispatch_sync(dispatch_get_main_queue(), ^{
        if (success) {
            [sectionModel.cellArray removeObject:cellModel];
            if (sectionModel.cellArray.count == 0) {
                [self.dataArray removeObject:sectionModel];
            }
        }else{
            cellModel.isSelected = NO;
        }
        [_collectionView reloadData];
    });
}];

评论已关闭。