无法使用 ForEach 循环 PHFetchResult

问题描述 投票:0回答:3

我目前正在开发一款适用于 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    
}

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

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

struct ShowImages: View {
    @ObservedObject var photos = PhotosAPI()

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

但我确实收到错误:

初始化程序“init(_:id:rowContent:)”要求“PHFetchResult”符合“RandomAccessCollection”

我今天一整天都在尝试解决这个问题,但没有成功,而且我在谷歌中找不到任何有用的东西。

有人知道如何让 PHFetchResults 循环它们吗?

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

ForEach(0..<photos.all.count) { index in
    Text("\(photos.all.object(at: index).localIdentifier)")
}  
swift swiftui photokit
3个回答
10
投票

您可以为

RandomAccessCollection
实现
PHFetchResult
或创建符合
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)
    }
}

然后您将能够将

PHFetchResultCollection
ForEach

一起使用
let collection = PHFetchResultCollection(fetchResult: fetchResult)

var body: some View  {
    ForEach(collection, id: \.localIdentifier) {
        ...
    }
}

2
投票

您可以使用

enumerate
方法枚举获取的结果对象的项目,例如:

https://developer.apple.com/documentation/photokit/phfetchresult/1620999-enumerateobjects


-1
投票

试试这个。

extension PHFetchResult<PHAsset> {
    func enumeratedPHAssets() -> [EnumeratedSequence<[PHAsset]>.Element] {
        Array(
            self.objects(
                at: IndexSet(0 ..< self.count)
            )
            .enumerated()
        )
    }
}

像这样使用它:

Foreach(results.enumratedPHAssets, id: \.offset) { idx, asset in 
    <#T##View#>
}
© www.soinside.com 2019 - 2024. All rights reserved.