简体   繁体   English

SWIFT 2-UICollectionView-缓慢滚动

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM