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
this is my cpu profiler in Instruments
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
}