Ios PHFETCH PHAsset选项的排序顺序与Photos.app相同

Ios PHFETCH PHAsset选项的排序顺序与Photos.app相同,ios,objective-c,swift,photokit,Ios,Objective C,Swift,Photokit,我正在使用新的PHFetchOptions的sortDescriptors从相机卷中获取相位集。似乎只有两个键可以排序:creationDate和modificationDate,它们都与您在Photos.app中看到的不一样 我错过什么了吗?我们如何才能让它发挥作用?我使用了以下代码来获取智能相册列表,其中包括“相机卷”: //获取智能相册 PHFetchResult*smartAlbums=[PHAssetCollection fetchAssetCollectionsWithType:PH

我正在使用新的PHFetchOptions的sortDescriptors从相机卷中获取相位集。似乎只有两个键可以排序:creationDate和modificationDate,它们都与您在Photos.app中看到的不一样


我错过什么了吗?我们如何才能让它发挥作用?

我使用了以下代码来获取智能相册列表,其中包括“相机卷”:

//获取智能相册
PHFetchResult*smartAlbums=[PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum子类型:PhasSetCollectionSubtypeAlbum常规选项:nil];
对于(NSInteger i=0;i

默认排序顺序是集合中资产(包括“摄影机卷”)的现有顺序。为选项传递“nil”将获得默认值。您可以重新排序摄影机卷中的图像,此代码将反映更改。

有一个超级简单的解决方案

  • 创建不带任何特定选项的获取结果

    // ...
    
    let options = PHFetchOptions()
    fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: options)
    
    if fetchResult.count > 0 {
      collectionView.reloadData()
    }
    
    // ...
    
  • 当您尝试加载某个资产时,只需使用反向索引

    // ...
    
    let reversedIndex = fetchResult.count - indexPath.item - 1
    let asset = fetchResult[reversedIndex] as! PHAsset
    
    // ...
    
  • 这样,您将获得与Photo.app中完全相同的流顺序


    希望对您有所帮助。:]

    继续@Majotron的回答,我想按照照片应用程序中的
    all photos
    相册的确切顺序获取所有用户的照片,并且只获取图像资源

    下面是我如何设置我的
    PHFetchOptions

    let allphotooption=PHFetchOptions()
    //仅获取图像资源
    allPhotosOption.predicate=NSPredicate(格式:“mediaType=%d”,PHAssetMediaType.image.rawValue)
    //获取所有相册收集的照片
    让userLibrary=PHAssetCollection.fetchAssetCollections(具有:.smartAlbum,子类型:.smartAlbumUserLibrary,选项:nil)。firstObject
    allPhotosResult=PHAsset.fetchAssets(在:userLibrary!中,选项:allPhotosOption)
    
    并使用TableView/CollectionView中的反向索引获取特定资产:

    let asset = allPhotosResult.object(at: allPhotosResult.count - indexPath.item - 1)
    
    如果您正在收听照片库的更改,也要小心,并相应地重新排列视图。当更改与删除相关时,使用fetchresult before changes获取反向索引,否则使用
    。fetchResultAfterChanges

    我是这样处理的:

    func photoLibraryDidChange(_ changeInstance: PHChange) {
    
        ... 
    
        DispatchQueue.main.sync {
            let originalCount = fetchResult.count
            fetchResult = changes.fetchResultAfterChanges
            if changes.hasIncrementalChanges {
    
                guard let collectionView = self.collectionView else { return }
    
                collectionView.performBatchUpdates({
    
                    if let removed = changes.removedIndexes, removed.count > 0 {
                        collectionView.deleteItems(at: removed.map({ IndexPath(item: originalCount - $0 - 1, section: 0) }))
                    }
                    if let inserted = changes.insertedIndexes, inserted.count > 0 {
                        collectionView.insertItems(at: inserted.map({ IndexPath(item: fetchResult.count - $0 - 1, section: 0) }))
                    }
                })
                // Avoid deleting and reloading same index path at one update
                collectionView.performBatchUpdates({
                    if let changed = changes.changedIndexes, changed.count > 0 {
                        collectionView.reloadItems(at: changed.map({ IndexPath(item: fetchResult.count - $0 - 1, section: 0) }))
                    }
                    changes.enumerateMoves { fromIndex, toIndex in
                        collectionView.moveItem(at: IndexPath(item: fetchResult.count - $0 - 1, section: 0),
                                                to: IndexPath(item: fetchResult.count - $0 - 1, section: 0))
                    }
                })
    
            } else {
                collectionView!.reloadData()
            }
    
            ...
    
        }
    }
    

    我知道这是一个老问题,但我认为分享一个有效的答案会很有用

    这就解决了这个问题中的问题
    PHFetchOptions for PHAsset的排序顺序与Photos.app的排序顺序相同,并且在iOS 13中工作

    PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
    PHFetchResult<PHAssetCollection *> *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
    PHFetchResult<PHAsset *> *allPhotos = [PHAsset fetchAssetsInAssetCollection:smartAlbums.firstObject options:allPhotosOptions];
    

    如果您正在观察更改,
    [[PHPhotoLibrary sharedPhotoLibrary]registerChangeObserver…
    为什么不呢?只要确保从photoLibraryDidChange:methodHey重新加载主线程上的数据,这种解决方案在某些情况下似乎是错误的。通过使用camera roll智能相册,我想出了一个可行的解决方案,您可能会发现这很有用()。看看
    fetchResult
    是如何设置的;]尽管您必须使用反向索引获取资产,因为它返回的集合
    0
    th资产是您的相机卷中的第一个资产,等等。您使用了我的答案还是想出了另一个答案?如果是的话,请接受我的回答。
    PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
    PHFetchResult<PHAssetCollection *> *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
    PHFetchResult<PHAsset *> *allPhotos = [PHAsset fetchAssetsInAssetCollection:smartAlbums.firstObject options:allPhotosOptions];
    
    [allPhotos objectAtIndex:(allPhotos.count - 1 - indexPath.item)];