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];
});
}];