简体   繁体   中英

CollectionView in TableViewCell scroll isn't smooth in swift3

这是我在TableViewCell中的CollectionView

In my project CollectionView in TableViewCell isn't display and I added

cell.collectionView.reloadData()

in my code. After I added, CollectionView displayed in TableViewCell , but ScrollView isn't smooth. How to solve this problem. If someone have any experience or ideas help me. Thanks.

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 in my project,

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

    }

}

Download Image Url Data in collectionView: UICollectionView, cellForItemAt indexPath: IndexPath delegate - ASYNCHRONOUSLY

Create a Class

First cache the image Data with respect to key Image URL

Why do we need to cache the data?

Because - While scrolling we don't need to download Image Every Time so Cache the already downloaded Image Data and return the cache data

I created a class name: AsyncImageLoader then I created a function which is a completion handler which returns the data after completion of downloading Image

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)) }
    }
}

} 

How to use AsyncImageLoader Class?

See below How I used in 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

        }
    }
 }

}
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale

After I added above code , my project become more smooth. I'll try the best and back with the best solution. Thanks

This is because you are directly getting data from url and then image from data in main thread. You should use image downloading library to download the image from url Here is the good third party to download image from url asynchronously.

https://github.com/rs/SDWebImage

Try with this I am 100% sure it will solve your problem.

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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