CollectionView in scrolling TableViewCell is not smooth in swift3

Here is my CollectionView in TableViewCell

In my project, CollectionView in TableViewCell not displayed, and I added

 cell.collectionView.reloadData() 

in my code. After I added, CollectionView displayed in TableViewCell , but ScrollView not smooth. How to solve this problem. If anyone has any experience or ideas, help me. Thank you

 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 } } 
0
source share
3 answers

Upload image url to collectionView: UICollectionView, cellForItemAt indexPath: IndexPath delegate - ASYNCHRONOUSLY

Create a class with a shared instance

First cache the image Data relative to the key URL of the image

Why do we need to cache data?

Because - when scrolling, we don’t need to load Image Every Time, therefore Cache already loaded Image Data and returned cache data

I created a class name: AsyncImageLoader , then I created a function that is a completion handler that returns data after the image has finished loading

 class AsyncImageLoader { //For caching the Image Data use NSCache var cache = NSCache<AnyObject, AnyObject>() //Shared Instance class var sharedLoader : AsyncImageLoader { struct Static { static let instance : AsyncImageLoader = AsyncImageLoader() } return Static.instance } //Completion handler function which returns the Image after complete downloading Image func imageForUrl(urlString: String, completionHandler: @escaping (_ image: UIImage?, _ url: String) -> ()) { let data = self.cache.object(forKey: urlString as AnyObject) as? NSData if let goodData = data { //check already we cached the image before or not let image = UIImage(data: goodData as Data) DispatchQueue.main.async(execute: {() in completionHandler(image, urlString) }) return } //if url Str is nil - check it or it crashes if urlString.characters.count <= 0 { DispatchQueue.main.async(execute: {() in completionHandler(nil, urlString) // returns nil }) return } let strToUrl = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)! URLSession.shared.dataTask(with: strToUrl, completionHandler: { (data, response, error) -> Void in if error == nil{ let image = UIImage(data: data!) self.cache.setObject(data as AnyObject, forKey: urlString as AnyObject) //setting cache of image with key as Image url DispatchQueue.main.async(execute: {() in completionHandler(image, urlString) //completion handler call }) } else { let image = UIImage(named: "logoBlue") //return dummy image if fails DispatchQueue.main.async(execute: {() in completionHandler(image, urlString) }) return } }).resume() } } 

How to use the AsyncImageLoader class?

See below. As I used in collectionView: UICollectionView, cellForItemAt indexPath: IndexPath

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { AsyncImageLoader.sharedLoader.imageForUrl(urlString: list.poster_image_url) { (image, url) -> () in DispatchQueue.main.async { cell.imageView.image = image } } } 
+1
source
 cell.layer.shouldRasterize = true cell.layer.rasterizationScale = UIScreen.main.scale 

After adding the code above, my project will become smoother. I will try better and better with a better solution. Thanks

0
source

This is because you directly receive data from the URL, and then images from the data in the main stream. You should use the image upload library to download the image from the url. Here is a good third party for asynchronously downloading the image from the url.

https://github.com/rs/SDWebImage

Try it, I'm 100% sure that it will solve your problem.

thanks

0
source

All Articles