I am looking for a way to smoothen my tableview. Since I have cells that need to download images from the URL, loading tableview cells one by one is very slow and makes the tableview lag. Moreover, the tableview will reload every time when I go back to previous cells. So I hope I could load the cells in batches of 15 with animation while loading. Any ideas of how I can do this? Any help is appreciated.
PS: Is my download function appropriate? Is there any other faster or better download function?
My code:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let post = posts[indexPath.row] // "post" are the firebase documents
if post.posttype == 1{
let cell = tableView.dequeueReusableCell(withIdentifier: TextPostCell.identifier, for: indexPath) as! TextPostCell
cell.titleText.text = post.title
cell.contentLable.text = post.content
cell.userPhoto.downloadImage(from: post.userphoto, placeHolder: UIImage(named: "notfound")!)
cell.username.text = post.sender
return cell
}else{
let cell = tableView.dequeueReusableCell(withIdentifier: ImageTextPostCell.identifier, for: indexPath) as! ImageTextPostCell
cell.titleText.text = post.title
cell.photoImage.downloadImage(from: post.photo![0], placeHolder: UIImage(named: "notfound")!)
print("success")
cell.userphoto.downloadImage(from: post.userphoto, placeHolder: UIImage(named: "notfound")!)
cell.username.text = post.sender
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// tableview selected
}
extension UIImageView{
func downloadImage(from url: String?, placeHolder placeholder: UIImage) {
print("Download Started")
if let safeString = url{
if let safeURL = URL(string: safeString){
getData(from: safeURL) { data, response, error in
if error != nil{
print("Tony's Notes: Problem retrieving data")
print(error!)
self.image = placeholder
}
// always update the UI from the main thread
DispatchQueue.main.async() { [weak self] in
if let safeData = data{
self?.image = UIImage(data: safeData)
return
}
}
}
}else{
self.image = placeholder
}
}else{
self.image = placeholder
}
}
func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}
}
CodePudding user response:
You may be looking for preloading: prefetch rows, and precancel rows.
https://developer.apple.com/documentation/uikit/uitableviewdatasourceprefetching