UICollectionView 加载延迟并且滚动非常颠簸

Posted

技术标签:

【中文标题】UICollectionView 加载延迟并且滚动非常颠簸【英文标题】:UICollectionView loading late and scrolling very bumpy 【发布时间】:2016-01-08 12:59:06 【问题描述】:

我正在设计一个集合视图,我试图在其中加载存储在数组中的字典中的图像和文本。我在这里的主要数组,即bannerarray 正在被其他一些函数解析。但是我遇到的问题是,当我滚动它以加载图像时,我的收藏视图变得不稳定,就好像它在滚动道路上有颠簸一样。我寻找了各种答案和代码,但都没有解决我的问题。

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    
        let cell = myCollectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! LandingPageCVC


        dispatch_async(dispatch_get_main_queue(),
            
                let categoryname = self.categoriesarray.objectAtIndex(indexPath.row).valueForKey("name")

                cell.layer.shouldRasterize = true;
                cell.layer.rasterizationScale = UIScreen.mainScreen().scale



                let imageurl = self.categoriesarray.objectAtIndex(indexPath.row).valueForKey("image") as! String

                if let url  = NSURL(string: imageurl),
                    data = NSData(contentsOfURL: url)
                

                    cell.lndngimage.image = UIImage(data: data)
                
                if indexPath.row % 2 == 0
                
                    cell.backgroundColor = UIColor(red: 67/255.0, green: 179/255.0, blue: 246/255.0, alpha: 1.0)
                
                else if indexPath.row % 3 == 0 && indexPath.row%2 != 0
                
                    cell.backgroundColor = UIColor.redColor()
                
                else
                
                    cell.backgroundColor = UIColor.greenColor()
                
                cell.lndngimg.text = categoryname as? String

        )



        return cell
    

请帮忙!提前致谢。

【问题讨论】:

lndngimg 一个 textView 或 textField 如果是,则将其更改为 label data = NSData(contentsOfURL: url) 在主线程中下载图像,这就是为什么UICollectionView 加载延迟或可能阻塞只需做一件事,创建下载图像队列并将其设置在主线程中。 另外,你不需要把这些代码放在dispatch_main()中,它已经在主队列上,层操作很长很多次。如果可能,将它们放在该单元格的 awakeFromNib 中。 @SunilChauhan 请解释一下,因为我正在执行异步类型。那么问题出在哪里? @KamalaDash:Bunty Madan 的评论是对的:NSData(contentsOfURL:url) 在主线程上从服务器下载数据,阻塞主线程导致 UI 卡住。所以删除该行并异步下载图像(即在后台线程中)。对于图片下载,我推荐github.com/rs/SDWebImage库,它会异步管理图片下载并为你缓存。! 【参考方案1】:
let queue = dispatch_queue_create("loader", nil)
dispatch_async(queue)  () -> Void in
//download the image do stuff
//like data = NSData(contentsOfURL: url)

//move back in main thread
dispatch_async(dispatch_get_main_queue(),
    //set the image.
    //cell.lndngimage.image = UIImage(data: data)
     )
 

所以data = NSData(contentsOfURL: url) 在主线程中下载图像,这就是为什么UICollectionView 加载延迟或可能会阻塞只需做一件事创建用于下载图像的队列并将其设置在主线程中。

【讨论】:

那卷轴呢? 是的,它可以工作,看到问题是你在主线程中进行下载,你滚动很重,所以你只需在 saparte 队列中下载东西,然后在主队列中更新 UI。【参考方案2】:

问题在于您使用了 NSData(contentsOfURL:) 方法,该方法同步加载图像并阻塞 UI。 AFNetworking 提供的异步方法不会导致此故障。

【讨论】:

请看github.com/AFNetworking/AFNetworking/blob/master/… 在 AlamoFire 中是否可能,因为我正在尝试在其中做所有事情。【参考方案3】:
NSData(contentsOfURL:url) 

在主线程上下载图像,这将阻止主线程更新 UI。您应该使用NSOperation 子类来下载您的图像。 Ray Wenderlich 对此主题有一个great tutorial。您还可以使用其他替代方法,例如 SDWebImage

希望有帮助!

编辑:

正如 Sunil 上面指出的,您不需要在 dispatch_async 块中完成大部分工作。您需要异步执行的唯一任务是图像下载。当您准备好更新UIImageView时,请确保跳回主队列

【讨论】:

以上是关于UICollectionView 加载延迟并且滚动非常颠簸的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 水平滚动延迟加载单元格

UIcollectionView 具有缓慢的图像加载和滚动

UICollectionView 在滚动 Alamofire 时将图像加载到错误的位置

UICollectionView 在重新加载数据时滚动不平滑

UICollectionView 神秘地延迟触摸直到滚动

iOS UICollectionView横向滑动并且横向加载数据