I am facing a problem when scrolling from top to bottom of my tableview
. The reusable cell shows old image until new image download is completed.
It sh
You must place an image for every cellForRowAtIndexPath
function, mean in your code you need to write else
condition for image operation and in that you need to place an placeholder image. Because tableview cells are reused when you scroll up and down, so that if you won't place any new content it will keeps the old content, that's why it shows old/duplicate content.
Set a default value for the imageViews as "nil" in your xib-file. This will make sure not to have an image on your cell before you load in a new one.
func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage? ){
//Set the imageViews to nil to make sure no other picture are set
imageViewItemPic.image = nil
imageViewCookerProfilePic.image = nil
//Check if img1 is not nil
if img1 != nil {
imageViewItemPic.image = img1
} else{
print("hi1")
imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!)
}
//Check if img2 is not nil
if img2 != nil {
imageViewCookerProfilePic.image = img2
} else{
imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!)
}
labelItemHeading.text = iteminfo.heading
labelItemDescription.text = iteminfo.description
}
just as i had the same problem; before reading this. i tried different ways such as the init and awakefromnib. the way to do it is just as soon as you receive the data before calling the func to update the whole UI.
Also, note im using a var restData
and the didSet
(this why it updates as soon as receiving the data from the viewcontroller, im not calling the func. if it was a func to call from the viewcontroller you would just put the placeholder image initially at the beginning of the func before downloading the new image and call it from the viewcontroller such as cell.updateUI(data: data)
Hope you guys find this useful. for me, im getting correct images without showing the preview image on the cell reuse :)
// tableview controller
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : RestCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell
//configure the cell to item
cell.restData = items[indexPath.row]
return cell
}
// UITableviewCell
class RestCell: UITableViewCell {
@IBOutlet var img : UIImageView!
@IBOutlet var lbl : UILabel!
// get data and update.
var restData: RestsModel! {
didSet {
// default img early placeholder set. Eliminates showing old pic in cell reuse
self.img.image = UIImage(named: "60x60placeholder.png")
// Update all values func
updateUI()
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Default image placeholder
//self.img.image = UIImage(named: "60x60placeholder.png")
}
// required init.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// Color of selected.
let myCustomSelectionColorView = UIView()
myCustomSelectionColorView.backgroundColor = UIColor(red: 234.0/255.0, green: 46.0/255.0, blue: 73.0/255.0, alpha: 0.1) //UIColor(netHex:0xFFFF434)
selectedBackgroundView = myCustomSelectionColorView
}
// updateUI func.
fileprivate func updateUI() {
// download the image
if ( self.restData.image != nil && self.restData.image != "") {
ImageLoader.sharedLoader.imageForUrl(urlString:self.restData.image, completionHandler:{(image: UIImage?, url: String) in
self.img.contentMode = UIViewContentMode.scaleAspectFit
self.img.image = image
})
} else {
self.img.image = UIImage(named: "60x60placeholder.png")
}
self.lbl.text = restData.name as String
}
}
You can set your default image in ItemTableViewCell
when the cell is initialized
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.image= defaultImage
}
Edit
func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage? ){
if img1 != nil {
imageViewItemPic.image = img1
}
else{
print("hi1")
imageViewItemPic.image = UIImage(named: "resto-placeholder.png")
imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!)
}
if img2 != nil {
imageViewCookerProfilePic.image = img2
}
else{
imageViewItemPic.image = UIImage(named: "resto-placeholder.png")
imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!)
}
labelItemHeading.text = iteminfo.heading
labelItemDescription.text = iteminfo.description
}
Its Very Simple Not Write Much Code Only Two Lines Solve Your Problem
cell.thumbnailimage.image = nil
cell.thumbnailimage.setImageWith(imageurl!)
Since it is a reusable cell, it indeed "reuses" the cell with the old image. Then you need to update it every time the cell is shown in cellForRowAtIndexPath
:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.image=placeholder_image
//then download image
}