无法使用 ForEach 循环 PHFetchResult

Vol*_*r88 1 xcode swift photokit swiftui

我目前正在开发一款适用于 iOS / macOS 的照片应用程序,但我正在努力使用 PhotoKit。

我确实创建了一个类来管理我所有的 PhotoKit 请求。

class PhotosAPI: ObservableObject {

@Published var all = PHFetchResult<PHAsset>()
@Published var allAlbums = PHFetchResult<PHAssetCollection>()
@Published var allSmartAlbums = PHFetchResult<PHAssetCollection>()

// Functions to get the Collections / Assets

}
Run Code Online (Sandbox Code Playgroud)

到目前为止,这部分正在工作,但现在我正在努力在我的视图中显示这些数据。

在我看来,我想在列表/网格中呈现所有资产

struct ShowImages: View {

    @ObservedObject var photos = PhotosAPI()

    var body: some View {
        List(photos.all, id: \.self) { item in
            Text("\(item)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我确实收到错误“初始化程序‘init(_:id:rowContent:)’要求‘PHFetchResult’符合‘RandomAccessCollection’”,我今天一整天都在尝试解决这个问题,但我没有成功,我也做不到。在谷歌上找不到任何有用的东西。

有谁知道我如何让 PHFetchResults 循环它们?

最后我能够用下面的代码显示图片。但这对我来说看起来是非常糟糕的代码。我更喜欢直接循环 PHFetchResult。有谁知道我怎样才能完成这件事?

ForEach(0..<photos.all.count) { index in
    Text("\(photos.all.object(at: index).localIdentifier)")
}  

       
Run Code Online (Sandbox Code Playgroud)

小智 5

您可以实现RandomAccessCollectionPHFetchResult创建符合RandomAccessCollection.

struct PHFetchResultCollection: RandomAccessCollection, Equatable {

    typealias Element = PHAsset
    typealias Index = Int

    let fetchResult: PHFetchResult<PHAsset>

    var endIndex: Int { fetchResult.count }
    var startIndex: Int { 0 }

    subscript(position: Int) -> PHAsset {
        fetchResult.object(at: fetchResult.count - position - 1)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以PHFetchResultCollection使用ForEach

let collection = PHFetchResultCollection(fetchResult: fetchResult)

var body: some View  {
    ForEach(collection, id: \.localIdentifier) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)