我在项目中设置了一个从JSON文件中获取数据的uicollectionview。然而,一切都运行良好,滚动非常慢,当视图滚动即将到来的单元格时,片刻之前会显示单元格的内容。
我尝试过使用dispatch_async
,但它仍然很慢而且很跳跃。
任何想法我做错了什么?
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let videoCell = collectionView.dequeueReusableCellWithReuseIdentifier("VideoCell", forIndexPath: indexPath) as UICollectionViewCell
let communityViewController = storyboard?.instantiateViewControllerWithIdentifier("community_id")
videoCell.frame.size.width = (communityViewController?.view.frame.size.width)!
videoCell.center.x = (communityViewController?.view.center.x)!
videoCell.layer.borderColor = UIColor.lightGrayColor().CGColor
videoCell.layer.borderWidth = 2
let fileURL = NSURL(string:self.UserVideosInfo[indexPath.row][2])
let asset = AVAsset(URL: fileURL!)
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
let time = CMTimeMake(asset.duration.value / 3, asset.duration.timescale)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
//self.showIndicator()
let NameLabelString = self.UserVideosInfo[indexPath.row][0]
let CommentLabelString = self.UserVideosInfo[indexPath.row][1]
let DateLabelString = self.UserVideosInfo[indexPath.row][3]
let buttonPlayUserVideo = videoCell.viewWithTag(1) as! UIButton
let nameLabel = videoCell.viewWithTag(2) as! UILabel
let commentUserVideo = videoCell.viewWithTag(3) as! UILabel
let dateUserVideo = videoCell.viewWithTag(4) as! UILabel
let thumbUserVideo = videoCell.viewWithTag(5) as! UIImageView
let deleteUserVideo = videoCell.viewWithTag(6) as! UIButton
buttonPlayUserVideo.layer.setValue(indexPath.row, forKey: "indexPlayBtn")
deleteUserVideo.layer.setValue(indexPath.row, forKey: "indexDeleteBtn")
dispatch_async(dispatch_get_main_queue()) {
nameLabel.text = NameLabelString
commentUserVideo.text = CommentLabelString
dateUserVideo.text = DateLabelString
self.shadowText(nameLabel)
self.shadowText(commentUserVideo)
self.shadowText(dateUserVideo)
if let cgImage = try? assetImgGenerate.copyCGImageAtTime(time, actualTime: nil) {
thumbUserVideo.image = UIImage(CGImage: cgImage)
}
}
}
//THIS IS VERY IMPORTANT
videoCell.layer.shouldRasterize = true
videoCell.layer.rasterizationScale = UIScreen.mainScreen().scale
return videoCell
}
答案 0 :(得分:1)
起初 - 您正在使用全局队列中的UI对象,似乎没有任何意义。这是被禁止的 - 或者行为将是不确定的。
辅助,最重要的操作是创建您在主队列上执行的缩略图。
考虑使用AVAssetImageGenerator
方法
public func generateCGImagesAsynchronouslyForTimes(requestedTimes: [NSValue], completionHandler handler: AVAssetImageGeneratorCompletionHandler)
而不是你自己的asyncs。
第三次,viewWithTag
操作非常繁重,导致subviews
上的枚举。考虑在单元格中为您需要的视图声明属性。
UPD:要在单元格中声明属性,请创建具有适当属性的UICollectionViewCell
的子类作为IBOutlets。然后,在您的视图控制器viewDidLoad
实现中,调用
collecionView.registerClass(<YourCellSubclass>.dynamicType, forCellWithReuseIdentifier:"VideoCell")
或者,如果在故事板中配置了集合视图单元格,请指定单元格的类并将其子视图连接到类&#39;直接在Interface Builder的单元格设置窗口中输出。
第四次,您的单元格正在被集合视图重用。每当您的单元格离开可见区域时,它将从集合视图中删除并放入重用队列。当您向后滚动到单元格时,会再次要求您的视图控制器提供单元格。并且您为每个新出现的单元格再次获取视频的缩略图。考虑通过collectionView的indexPath.item
索引将已存取的缩略图存储在某个数组中来缓存这些缩略图。