When I'm populating new data in my tableView Controller, my top cell is being rewrite by the bottom one. Let me explain. I have one image that is loading async in the latest cell row, in the bottom. All the other cells are loading static with an image that is in the app. When I scroll down my app and display my bottom cell which have a different image than the others cells, and I scroll up again, I see the first shop image has changed to the dynamic one loaded in the bottom cell. Does anyone know why this is happening?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : shopsTableViewCell = tableView.dequeueReusableCellWithIdentifier("shopCell", forIndexPath: indexPath) as! shopsTableViewCell
cell.index = indexPath.row
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
let apiCall = webApi()
dispatch_async(backgroundQueue, {
apiCall.downloadPhotoAsync("http://api-ytyg.wbbdev.com/files/shops/\(shops[indexPath.row].id)/\(shops[indexPath.row].featured_img)"){(image: UIImage?) -> Void in
dispatch_async(dispatch_get_main_queue()){
if(image != nil){
if (cell.index == indexPath.row){
// shops[indexPath.row].photo = image!
cell.shopImg?.image = image
}
}else{
shops[indexPath.row].photo = UIImage.init(named: "No_Image_Available.jpg")!
}
}
}
})
cell.shopName?.text = shops[indexPath.row].name
cell.shopDescription?.text = shops[indexPath.row].address
cell.label1?.text = shops[indexPath.row].city + " | " + shops[indexPath.row].distance + "Km"
cell.becomeFirstResponder()
return cell
}
it is because your cells are being reused :
// this line initialize a cell of type shopsTableViewCell
//if no cell can be reused, get an already used cell else
let cell : shopsTableViewCell
= tableView.dequeueReusableCellWithIdentifier("shopCell",
forIndexPath: indexPath) as! shopsTableViewCell
so image and other data should be the last image and data of the dequeued cell.
To avoid this, you shall implement prepareForReuse
in the cell class file to reset data and image. docs of apple about prepareForReuse func
From Apple docs :
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
//Example :
override func prepareForReuse() {
super.prepareForReuse()
//Do reset here
this.shopImg?.image = nil
this.shopName?.text = ""
this.shopDescription?.text = ""
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With