我目前有一个自定义 UICollection,它从用户的相机胶卷加载用户视频库。现在我现在可以将所有视频添加到一个数组中;并打印出正确的视频数量;但是我的 UICollection 没有显示我库中的所有视频(共 119 个)。任何人都知道为什么会发生这种情况?
这是我的代码:
struct Media {
var image:UIImage?
var videoURL:NSURL?
}
var mediaArray = [Media]()
func grabPhotos(){
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 fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
if fetchResult.count > 0 {
for i in 0..<fetchResult.count{
var mediaItem = Media()
//Used for fetch Image//
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 400, height: 400), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
mediaItem.image = imageOfVideo;
//Used for fetch Video//
imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
if let asset = avAsset as? AVURLAsset {
let videoData = NSURL(string: "\(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
mediaItem.videoURL = videoData!
self.mediaArray.append(mediaItem)
print(self.mediaArray.count)
}
})
})
}
}
else{
//showAllertToImportImage()//A function to show alert
}
}
}
还有我的 cellForItemAt
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! VideoSelectionCVCell
cell.uploadedFile.image = mediaArray[indexPath.row].image
return cell
}
& 在我的 viewWillAppear 中,我创建了 UICollection:
let flowLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(VideoSelectionCVCell.self, forCellWithReuseIdentifier: cellId)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.clear
self.view.addSubview(collectionView)
我认为正在发生的事情是在 grabPhotos() 发生之前加载屏幕;并且 grabPhotos() 直到屏幕加载后才完成。我还在 viewWillAppear 中创建了我的 UICollection,因此这将使它成为私有(private)事件(如果我是正确的)。所以我想要解决这个问题,我需要公开 UICollectionView,但是如果我以编程方式执行此操作 + 在我的 View 中创建它,我会怎么做?
最佳答案
我认为有几种不同的方法可以解决这个问题。
将您的远程图像加载到 cellforitemat 中
- 在 Viewdidload 中添加您的 Collection View ,然后在函数调用 grabphotos 的末尾添加。
- 在您的 grabphotos 函数中,在获得 fetchResult 后调用 collectionView.reloadData()。
- 将 imgManager.requestImage 移动到 cellforitem 中。这样,您只在渲染单元格时加载每个图像。在更新 collectionView 之前,用户不会等待所有图像加载。如果您担心性能,可以添加预取。
使用 DispatchGroup
如果您真的很想在更新 collectionView 之前加载所有图像,您可以创建一个 DispatchGroup 来跟踪图像下载,然后在完成后更新 collectionView。
struct Media {
var image:UIImage?
var videoURL:NSURL?
}
var mediaArray = [Media]()
let loadContentGroup = DispatchGroup()
func grabPhotos(){
loadContentGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let `self` = self else { return }
self.collectionView.reloadData()
}
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 fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
if fetchResult.count > 0 {
for i in 0..<fetchResult.count{
var mediaItem = Media()
loadContentGroup.enter()
//Used for fetch Image//
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 400, height: 400), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
mediaItem.image = imageOfVideo;
//Used for fetch Video//
imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
if let asset = avAsset as? AVURLAsset {
let videoData = NSURL(string: "\(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
mediaItem.videoURL = videoData!
self.mediaArray.append(mediaItem)
print(self.mediaArray.count)
self.loadContentGroup.leave()
}
})
})
}
}
else{
//showAllertToImportImage()//A function to show alert
}
}
}
关于arrays - UICollectionView 没有显示我的所有数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43750020/