我正在努力解决从iPhone到collectionView
显示照片库的问题。
如果画廊内有50张照片,一切正常。问题是,当有人拥有数千张照片时,画廊加载了10秒钟,这对我的应用程序来说并不好。
当我从Facebook加载图像时,会出现同样的问题。应用程序等待它下载每张照片然后显示。我想在加载操作期间逐个显示图像,而不是等待它全部加载。
我知道我应该使用DispachQueue
我做了但是有一些我看不到的错误
这是我用来从iPhone图库中获取图像的代码:
func grapPhotos() {
let imgManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResulat : PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) {
if fetchResulat.count > 0 {
for i in 0..<fetchResulat.count {
imgManager.requestImage(for: fetchResulat.object(at: i), targetSize: CGSize(width: 200, height:200), contentMode: PHImageContentMode.aspectFill, options: requestOptions, resultHandler: {
(image, eror) in
self.imageArray.append(image!)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
})
}
} else {
print("You have no photos")
self.collectionView.reloadData()
}
}
}
以及在collectionView
中显示它们的代码:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "galleryCell", for: indexPath) as! GalleryCollectionViewCell
let image = self.imageArray[indexPath.row]
DispatchQueue.main.async {
cell.gelleryImages.image = image
}
return cell
}
我的Facebook课程可能存在同样的问题,所以我将非常感谢你的帮助。
答案 0 :(得分:5)
您需要的是将fetchResult属性添加到集合视图控制器并在viewDidLoad方法中获取图像资源。
var fetchResult: PHFetchResult<PHAsset> = PHFetchResult()
func fetchAssets() {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
}
override func viewDidLoad() {
super.viewDidLoad()
fetchAssets()
}
下一步是扩展UIImageView以请求图像数据在完成时异步设置其图像。
func fetchImage(asset: PHAsset, contentMode: PHImageContentMode, targetSize: CGSize) {
let options = PHImageRequestOptions()
options.version = .original
PHImageManager.default().requestImage(for: asset, targetSize: targetSize, contentMode: contentMode, options: options) { image, _ in
guard let image = image else { return }
switch contentMode {
case .aspectFill:
self.contentMode = .scaleAspectFill
case .aspectFit:
self.contentMode = .scaleAspectFit
}
self.image = image
}
}
现在,您可以在集合视图cellForItemAt方法中一次一个地获取图像:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell
let asset = fetchResult.object(at: indexPath.row)
cell.imageView.fetchImage(asset: asset, contentMode: .aspectFit, targetSize: cell.imageView.frame.size)
return cell
}
不要忘记返回numberOfItemsInSection方法的fetchResult计数。
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return fetchResult.count
}
答案 1 :(得分:0)
你有没有看过SDWebImage?它内置了缓存支持,因此设备不必每次都下载以前下载过的图像。它还具有实现非常简单的优点!