Home > front end >  Scroll is not smooth when showing long text post in Label cells using CollectionView
Scroll is not smooth when showing long text post in Label cells using CollectionView

Time:12-14

i am making app with CollectionView cells using Swift and i fetching posts from my WordPress Website, i want to show posts in CollectionView cell and i want to show full text in Label, but the problem is that when is show posts on CollectionView , scroll is not smooth and sometimes it just stop scrolling for some seconds, this is my code to fetch posts..

 func fetchPostData(completionHandler: @escaping ([Post]) -> Void ) {
   
   
      let url = URL(string: "https://www.sikhnama.com/wp-json/wp/v2/posts/?categories=5&per_page=30&page=\(page)\(sortBy)")!
      
      let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
          
          guard let data = data else {return}
          
          do {
              
              let postsData = try JSONDecoder().decode([Post].self, from: data)
              
              completionHandler(postsData)
              DispatchQueue.main.async {
                  self.collectionView.reloadData()
                  SVProgressHUD.dismiss()
                  
              }
          }
          
          catch {
              
              let error = error
              print(String(describing: error))
          }
          
          
          
      }
    task.resume()
      
      
      
      
      
      
  }

this is in my CollectionViewCell

 override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
   setNeedsLayout()
   layoutIfNeeded()
   let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
   var frame = layoutAttributes.frame
   frame.size.height = ceil(size.height)
   layoutAttributes.frame = frame
   return layoutAttributes

}

and this is how i convert html to text

titleLabel.text = String(htmlEncodedString: hukam.content.rendered)

this is in Viewdid load

 let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
            layout.itemSize = UICollectionViewFlowLayout.automaticSize
            layout.estimatedItemSize = CGSize(width: view.frame.width-20, height: 40)

this is collectionView Extension

extension StatusViewController: UICollectionViewDataSource {

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
    return newsData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    
       
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "postcell", for: indexPath) as! StatusViewCell
        
     
        
        cell.setup(with: newsData[indexPath.row])
        
    cell.layer.shouldRasterize = true
    cell.layer.rasterizationScale = UIScreen.main.scale
      
        
        return cell
    
    
    
    
    
}

and this is how i setup constrain of label

enter image description here

this is my cpu profiler in Instruments

enter image description here

this is how i convert html to text

    extension String {
    init(htmlEncodedString: String) {
        self.init()
        guard let encodedData = htmlEncodedString.data(using: .utf8) else {
            self = htmlEncodedString
            return
        }
        
        let attributedOptions: [String : Any] = [
            convertFromNSAttributedStringDocumentAttributeKey(NSAttributedString.DocumentAttributeKey.documentType): convertFromNSAttributedStringDocumentType(NSAttributedString.DocumentType.html),
            convertFromNSAttributedStringDocumentAttributeKey(NSAttributedString.DocumentAttributeKey.characterEncoding): String.Encoding.utf8.rawValue
        ]
        
        do {
            let attributedString = try NSAttributedString(data: encodedData, options: convertToNSAttributedStringDocumentReadingOptionKeyDictionary(attributedOptions), documentAttributes: nil)
            self = attributedString.string
        } catch {
            print("Error: \(error)")
            self = htmlEncodedString
        }
    }
}


fileprivate func convertFromNSAttributedStringDocumentAttributeKey(_ input: NSAttributedString.DocumentAttributeKey) -> String {
    return input.rawValue
}


fileprivate func convertFromNSAttributedStringDocumentType(_ input: NSAttributedString.DocumentType) -> String {
    return input.rawValue
}




fileprivate func convertToNSAttributedStringDocumentReadingOptionKeyDictionary(_ input: [String: Any]) -> [NSAttributedString.DocumentReadingOptionKey: Any] {
    return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.DocumentReadingOptionKey(rawValue: key), value)})
}

CodePudding user response:

I made a new application using tableView, there were cuts at the end of the descriptions of the news in my application, so I chose the label from the main Storyboard menu and made Autoshirink as Minimum font scale, I reduced it by 0.5 and it worked. don't forget to make the lines zero because zero means you have infinite lines

CodePudding user response:

This is how I parsed the data from JSON. I created a model, I put that model in an empty array here, then I added the data I parsed into my array, then when I show it in the cell, I print it according to the indexPath.row of this array.

func fetchNews(){
        let urlRequest = URLRequest(url: URL(string: "https://inshorts.deta.dev/news?category=" categoryId)!)
        loading.startAnimating()
        let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
            if error != nil {
                print(error?.localizedDescription)
                return
            }
            
            do{
                let json = try JSONSerialization.jsonObject(with: data!) as! [String : AnyObject]
                if let articklesFromJson = json["data"] as? [[String : AnyObject]]{
                    for articleFromJson in articklesFromJson {
                        let article = NewsModel()
                        if let title = articleFromJson["title"] as? String, let author = articleFromJson["author"] as? String, let content = articleFromJson["content"] as? String, let imageUrl = articleFromJson["imageUrl"] as? String {
                            article.author = author
                            article.content = content
                            article.title = title
                            article.imageUrl = imageUrl
                        }
                        self.News?.append(article)
                    }
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
        }catch {
            print("error")
        }
        }
        task.resume()
       
    }

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! tableCell
    cell.titleCell.text = self.News?[indexPath.item].title
    cell.authorCell.text = self.News?[indexPath.item].author
    cell.textCell.text = self.News?[indexPath.item].content
    cell.imgCell.dowloadImage(from: (self.News![indexPath.item].imageUrl!))
    loading.stopAnimating()
    return cell
}
  • Related