[英]SWIFT 2 - UICollectionView - slow scrolling
I have setup a uicollectionview in my project that get data from a JSON file. 我在我的项目中设置了一个uicollectionview,它从JSON文件获取数据。 Everything works good however, the scrolling is very slow and when the view is scrolling the coming cell, for few moments shows the content of the cell before. 一切都很好,但是,滚动非常缓慢,并且当视图滚动即将到来的单元格时,一会儿会显示之前单元格的内容。
I have tried using dispatch_async
but it still very slow and jumpy. 我试过使用dispatch_async
但它仍然非常缓慢且跳跃。
any Idea what am I doing wrong? 任何想法我在做什么错?
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
}
At first - you are working with UI objects from global queue and seems like without any purpose. 首先 -您正在使用全局队列中的UI对象,并且似乎没有任何目的。 That is forbidden - or behavior will be undefined. 禁止这样做-否则行为将不确定。
Secondary , the mostly heavy operation is creation of thumbnail which you perform on main queue. 其次 ,最繁重的操作是创建在主队列上执行的缩略图。 Consider using of the AVAssetImageGenerator
's method 考虑使用AVAssetImageGenerator
的方法
public func generateCGImagesAsynchronouslyForTimes(requestedTimes: [NSValue], completionHandler handler: AVAssetImageGeneratorCompletionHandler)
instead of your own asyncs. 而不是您自己的异步。
At third , viewWithTag
is pretty heavy operation causing enumeration on subviews
. 第三 , viewWithTag
是非常繁重的操作,导致viewWithTag
subviews
枚举。 Consider to declare properties in the cell for views which you need. 考虑在单元格中声明所需视图的属性。
UPD: to declare properties in a cell, create subclass of UICollectionViewCell
with appropriate properties as IBOutlets. UPD:要在单元格中声明属性,请创建具有适当属性的UICollectionViewCell
子类作为IBOutlets。 Then, in your view controller viewDidLoad
implementation, call 然后,在您的视图控制器viewDidLoad
实现中,调用
collecionView.registerClass(<YourCellSubclass>.dynamicType, forCellWithReuseIdentifier:"VideoCell")
Or, if your collection view cell is configured in the Storyboard, specify the class of the cell and connect its subviews to class' outlets directly in the cell's settings window in Interface Builder. 或者,如果在情节提要中配置了收藏视图单元格,请指定单元格的类并将其子视图直接在Interface Builder中的单元格设置窗口中连接到类的出口。
At fourth , your cells are being reused by a collection view. 第四 ,您的单元格被集合视图重用。 Each time your cell is going out of visible area, it is removed from collection view and is put to reuse queue. 每当您的单元格超出可见区域时,它就会从集合视图中删除,并放入重用队列。 When you scroll back to the cell, your view controller is asked again to provide a cell. 当您滚动回到单元格时,再次要求您的视图控制器提供一个单元格。 And you're fetching the thumbnail for the video again for each newly appeared cell. 然后,您将为每个新出现的单元格再次获取视频的缩略图。 Consider caching of already fetched thumbnails by storing them in some array by collectionView's indexPath.item
index. 考虑通过collectionView的indexPath.item
索引将已提取的缩略图存储在某个数组中来进行indexPath.item
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.