Reputation: 1697
When I select a cell in an UITableView
I change its image, but a cell out of sight (need to scroll down to see the affected cell) gets affected which means that the affected cell also change its image. It must be something about the reused cells, but I can't figured out why and how to solve this problem. Hope you guys can help me, thank you.
Another thing is, the cell should not reset its image when it get scroll out of sight.
Here is my delegates for the UITableView
:
//UITableview delegate
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Arecipe.IngredientArr.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (tableView == IngrediensTableView) {
print("Cell")
var cell = tableView.dequeueReusableCellWithIdentifier("Cell")
let ingredient = self.Arecipe.IngredientArr[indexPath.row]
if ((cell == nil)) {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
cell!.imageView?.image = UIImage(named: "Ingr_Uncheck")
}
cell!.textLabel?.text = ingredient.UnitValue + " " + ingredient.UnitName + " " + ingredient.Name
cell!.selectionStyle = .None
return cell!
}
return UITableViewCell()
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Row \(indexPath.row) selected")
if (tableView == IngrediensTableView) {
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
print(cell.textLabel?.text)
if(cell.imageView?.image == UIImage(named: "Ingr_Uncheck")) {
cell.imageView?.image = UIImage(named: "Ingr_Check")
} else {
cell.imageView?.image = UIImage(named: "Ingr_Uncheck")
}
}
}
Upvotes: 1
Views: 881
Reputation: 726479
the affected cell also change its image. It must be something about the reused cells
That's right! The reason is that you set Ingr_Uncheck
image only to a brand-new cell. If a cell gets reused, you skip setting the image, keeping whatever was set there previously.
The decision to set Ingr_Check
vs. Ingr_Uncheck
image needs to be done based on the state of your table's model.
if(myCodeThatChecksIfRowIsChecked(indexPath.row)) {
cell!.imageView?.image = UIImage(named: "Ingr_Check")
} else {
cell!.imageView?.image = UIImage(named: "Ingr_Uncheck")
}
Now the proper image is set to both new and reused cells, making sure that reusing a previously checked cell does not change the visuals.
The code myCodeThatChecksIfRowIsChecked
needs to rely on some stored state that you change inside your didSelectRowAtIndexPath
method. This is where you need to maintain a list of row numbers for cells that have been checked. This is also the list that you consult to decide if a cell should be unchecked or not: doing it based on the image is not the correct approach.
Upvotes: 2
Reputation: 42977
You could resolve this in two ways. Either set the image to nil
cellForRow
cell.imageView?.image = nil
Or if you have custom class for the cell, implement
override func prepareForReuse() {
imageView?.image = nil
}
Reset with nil or with the default image
Upvotes: 0
Reputation: 1265
u cant compare 2 uiimage by "=="
if(cell.imageView?.image == UIImage(named: "Ingr_Uncheck"))
use this
if( [UIImagePNGRepresentation(cell.imageView?.image) isEqual:UIImagePNGRepresentation(UIImage(named: "Ingr_Uncheck"))] == YES)
Upvotes: 1