UITableViewCell 中的 UICollectionView 在 swift 3 中滚动不流畅

Posted

技术标签:

【中文标题】UITableViewCell 中的 UICollectionView 在 swift 3 中滚动不流畅【英文标题】:CollectionView in TableViewCell scroll isn't smooth in swift3 【发布时间】:2017-05-09 09:42:48 【问题描述】:

在我的项目CollectionViewTableViewCell 没有显示,我添加了

cell.collectionView.reloadData()

在我的代码中。我添加后,CollectionView 显示在TableViewCell 中,但是 ScrollView 不流畅。如何解决这个问题呢。如果有人有任何经验或想法帮助我。谢谢。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "homecell") as! HomeCategoryRowCell

    let mainThemeList = mainHomeThemeTable[(indexPath as NSIndexPath).row]

    DispatchQueue.main.async 
        cell.categoryTitle.text = mainThemeList.main_name
        cell.collectionView.reloadData()
    


    return cell

我项目中的CollectionView,

extension HomeCategoryRowCell : UICollectionViewDataSource 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

        debugPrint("assetsTable count \(assetsTable.count)")
        return assetsTable.count
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! HomeVideoCell

        let list = assetsTable[(indexPath as NSIndexPath).row]
        let url2 = NSURL(string:list.poster_image_url)
        let data2 = NSData(contentsOf:url2! as URL)
        //  debugPrint(list.poster_image_url)
        DispatchQueue.main.async()
            cell.movieTitle.text = list.name
            cell.imageView.image = UIImage(data: data2! as Data)

        

        return cell

    


【问题讨论】:

只在tableview的cellforrow方法中给collectioview的委托和数据源,不要重新加载colletioview collectionView.delegate = self collectionView.dataSource = self 我已经添加了。但没有解决问题@JeckyModi 你在 collectionview 中加载了什么?如果是图片,请确保图片不是高分辨率的。 你为什么使用DispatchQueue.main.async?你似乎不在另一个线程上。你试过没有吗? DispatchQeue.main.async for cell.categoryTitle.text = mainThemeList.main_name。如果我没有使用 Dispcatch,后台线程有问题。@pesch 【参考方案1】:

collectionView: UICollectionView, cellForItemAt indexPath: IndexPathdelegate - ASYNCHRONOUSLY 中下载图片 URL 数据

创建一个类

首先缓存与关键图像URL相关的图像数据

为什么我们需要缓存数据?

因为 - 滚动时我们不需要每次都下载图像所以缓存已经下载的图像数据并返回缓存数据

我创建了一个类名:AsyncImageLoader 然后我创建了一个函数,它是一个完成处理程序,它在完成下载图像后返回数据

class AsyncImageLoader 

static let cache = NSCache<NSString, NSData>()

class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) 

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async 

        if let data = self.cache.object(forKey: url.absoluteString as NSString) 
            DispatchQueue.main.async  completionHandler(UIImage(data: data as Data)) 
            return
        

        guard let data = NSData(contentsOf: url) else 
            DispatchQueue.main.async  completionHandler(nil) 
            return
        

        self.cache.setObject(data, forKey: url.absoluteString as NSString)
        DispatchQueue.main.async  completionHandler(UIImage(data: data as Data)) 
    


 

如何使用 AsyncImageLoader 类?

见下文我如何在collectionView: UICollectionView, cellForItemAt indexPath: IndexPath中使用

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let yourCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCollectionCell", for: indexPath) as! CustomCollectionCell

    yourCell.url = URL(string: "\(item_ImageUrl)")

   return yourCell

CustomCollectionCell

class CustomCollectionCell: UICollectionViewCell 

@IBOutlet weak var cellImageDisplayView: UIImageView!

var url: URL? 
    didSet 
        if let url = url 

           cellImageDisplayView.image = nil

            AsyncImageLoader.image(for: url, completionHandler:  (image) in

                DispatchQueue.main.async 

                    if let img = image 

                        self.cellImageDisplayView.image = img


                    else
                        let dummyImage = UIImage(named: "img_u")
                        self.cellImageDisplayView.image = dummyImage
                    
                

            )

        else

            let dummyImage = UIImage(named: "img_u")
            self.cellImageDisplayView.image = dummyImage

        
    
 


【讨论】:

哇!添加您的代码后,我的项目现在很顺利。感谢您的最佳答案!【参考方案2】:
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale

添加以上代码后,我的项目变得更加流畅。我会尽力而为,并以最好的解决方案返回。谢谢

【讨论】:

【参考方案3】:

这是因为您直接从 url 获取数据,然后从主线程中的数据获取图像。您应该使用图片下载库从 url 下载图片 这是从 url 异步下载图片的好第三方。

https://github.com/rs/SDWebImage

试试这个我100%肯定它会解决你的问题。

谢谢

【讨论】:

以上是关于UITableViewCell 中的 UICollectionView 在 swift 3 中滚动不流畅的主要内容,如果未能解决你的问题,请参考以下文章

collectionView:didSelectItemAtIndexPath:没有被调用

UITableViewCell 中的 UIDatePicker 更新 UITableViewCell 文本标签

更改 UITableViewCell 中的对象也更改了重用 UITableViewCell 的对象

确定 UITableViewCell 中的 UIButton

UITableViewCell 事件中的 UIButton 不起作用

UITableViewCell 中的 UICollectionView