xap*_*hod 10 objective-c photos ios ios8
我正在使用Photos框架编写iOS8应用程序.我真的很喜欢PHFetchResultChangeDetails.但有一些我不明白的事情:当我使用以下代码将新照片保存到相机胶卷时,我会回来插入和更改.我希望只插入.
使它具体化:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest* newPhotoChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollectionChangeRequest* albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:_album];
[albumChangeRequest addAssets:[NSArray arrayWithObject:newPhotoChangeRequest.placeholderForCreatedAsset]];
...
Run Code Online (Sandbox Code Playgroud)
操作是使用上面的代码插入3张照片.之前:ipad上的5张照片.之后:ipad中的8张照片.PHFetResultChangeDetails处理程序上的断点显示:
(lldb) po insertionIndexPaths
<__NSArrayM 0x7913be10>(
<NSIndexPath: 0x78e39020> {length = 2, path = 0 - 5},
<NSIndexPath: 0x78e3c910> {length = 2, path = 0 - 6},
<NSIndexPath: 0x78e39480> {length = 2, path = 0 - 7}
)
Run Code Online (Sandbox Code Playgroud)
- >好:有道理!这些是我刚插入的照片(最后3个索引路径).
(lldb) po changeIndexPaths
<__NSArrayM 0x78e3c420>(
<NSIndexPath: 0x78e3c7e0> {length = 2, path = 0 - 2},
<NSIndexPath: 0x78e3c7a0> {length = 2, path = 0 - 3},
<NSIndexPath: 0x78e3c7b0> {length = 2, path = 0 - 4}
)
Run Code Online (Sandbox Code Playgroud)
- >不要理解:为什么这些被认为是"改变了"?这些是相机胶卷上的现有照片......我没有对它们做任何事情.
谢谢你的帮助.
更新:看起来它可能与选择有关.我忽略了提到,当已经选择了一些细胞时会发生这种情况.我所看到的是,当在collectionView的末尾插入新项目时,一些选定的单元格被随机取消选择 - 我认为那些具有changeIndexPaths.哇,太糟糕了 - 我看不出我的代码是如何做到的!任何提示?
UPDATE2:所以,看起来虚假的changeIndexPaths总是直接在插入路径之前的3个indexPaths(总是在结尾处).为什么?!
UPDATE3:我还看到UICollectionView的performBatchUpdates崩溃,如果数据源事先是正确的,如果有插入和重新加载的话.例如,当更改看起来像这样:
<PHFetchResultChangeDetails: 0x1742b91a0>
before=<PHFetchResult: 0x1702b5d20> count=31,
after=<PHFetchResult: 0x1702b5ea0> count=33,
hasIncremental=1 deleted=(null),
inserted=<NSMutableIndexSet: 0x17444aef0>[number of indexes: 2 (in 2 ranges), indexes: (30 32)],
changed=<NSMutableIndexSet: 0x17444a9b0>[number of indexes: 4 (in 2 ranges), indexes: (27-29 31)],
hasMoves=0
Run Code Online (Sandbox Code Playgroud)
...然后我的应用程序在performBatchUpdates崩溃,但有异常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 31 from section 0 which only contains 31 items before the update'
Run Code Online (Sandbox Code Playgroud)
这是performBatchUpdates的代码,我直接从Apple文档(!)复制,因此我认为没有理由为changeIndexPaths包含索引31,因为在插入之前,count = 31:
[self.collectionView performBatchUpdates:^{
if( deletionIndexPaths.count )
[self.collectionView deleteItemsAtIndexPaths:deletionIndexPaths];
if( insertionIndexPaths.count )
[self.collectionView insertItemsAtIndexPaths:insertionIndexPaths];
if( changeIndexPaths.count )
[self.collectionView reloadItemsAtIndexPaths:changeIndexPaths];
if( moveBlock )
moveBlock(self.collectionView);
} ...
Run Code Online (Sandbox Code Playgroud)
小智 5
回复:更新 3
不管示例代码怎么说,changedIndexes 不能像这样在 performBatchUpdates 中使用。
该指数PHFetchResultChangeDetails.changedIndexes是相对于原来的取结果后在removedIndexes指标被删除,之后在insertedIndexes新的索引添加。
但是 UITableView 和 UICollectionView API 要求 reloadItems* 方法在批量更新中调用时具有任何其他更改之前的索引。
要解决此问题,请重新加载并在批量更新之外移动条目,例如:
[self.collectionView performBatchUpdates:^{
if( deletionIndexPaths.count )
[self.collectionView deleteItemsAtIndexPaths:deletionIndexPaths];
if( insertionIndexPaths.count )
[self.collectionView insertItemsAtIndexPaths:insertionIndexPaths];
} ... ]
if( changeIndexPaths.count )
[self.collectionView reloadItemsAtIndexPaths:changeIndexPaths];
if( moveBlock )
moveBlock(self.collectionView);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
673 次 |
| 最近记录: |