Reputation: 191
I am trying to populate aa UICollectionView with thumbnails of videos and photos extracted from the user's camera roll. I loaded all the media from the camera roll in the form of PHAsset
inside the array images
as declared here:
var images = [PHAsset]()
The if-then
loop checks to see if the PHAsset
is either a image or a video. If it is a image, it simply adds it to the collection view. However, I am not sure how I would add a thumbnail of a video to the collection view. Any help is appreciated.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoLibraryCollectionViewCell", for: indexPath) as! PhotoLibraryCollectionViewCell
let asset = images[indexPath.row]
if asset.mediaType == PHAssetMediaType.image {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: asset, targetSize: CGSize(width: 138, height: 138), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
cell.imageView.image = thumbnail
} else {
// code to add the thumbnail of the video to the collection view
}
return cell
}
Edit: I tried removing the if-then method but the collection view shows no thumbnail for the videos at all.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoLibraryCollectionViewCell", for: indexPath) as! PhotoLibraryCollectionViewCell
let asset = images[indexPath.row]
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
option.isNetworkAccessAllowed = true
manager.requestImage(for: asset, targetSize: CGSize(width: 138, height: 138), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
cell.imageView.image = thumbnail
return cell
}
If you look at the link below, I clearly have a video in my camera roll but it doesn't show up in the collection view: https://i.sstatic.net/EIP8W.jpg
Upvotes: 1
Views: 7010
Reputation: 4918
When using PHAsset requestImage(for:targetSize:contentMode:options:resultHandler:)
works for both Photos and Videos.
You can use this method for both photo and video assets for a video asset, an image request provides a thumbnail image or poster frame.
So just drop the if statement and call request the thumbnail for both types.
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: asset, targetSize: CGSize(width: 138, height: 138), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
cell.imageView.image = thumbnail
Edit: Make sure network access is allowed
options.isNetworkAccessAllowed = true
Upvotes: 8
Reputation: 5259
you can try to use PHCachingImageManager
as in Apple sample project
let cachingImageManager = PHCachingImageManager()
and somewhere before loading the items call try to load the caches
func updateCache() {
//Update the size here
let size: CGSize = CGSize(width: 138, height: 138)
cachingImageManager.startCachingImages(for: images, targetSize: size, contentMode: .aspectFit, options: nil)
}
then loading the thumbnail for images and videos would be like this
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoLibraryCollectionViewCell", for: indexPath) as! PhotoLibraryCollectionViewCell
let asset = images[indexPath.row]
let size = CGSize(width: 138, height: 138)
let option = PHImageRequestOptions()
option.isSynchronous = true
cachingImageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFit, options: option) { image, info in
cell.imageView.image = image
}
return cell
}
Note: loading the images from the PHAsset
without cacheing might lead to a memory issue
you might need to create another PHCachingImageManager
in case of items change in the images array
Upvotes: 1