Loc Dai Le
Loc Dai Le

Reputation: 1697

Selecting a cell in UITableView another one gets affected

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

Answers (3)

Sergey Kalinichenko
Sergey Kalinichenko

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

Anil Varghese
Anil Varghese

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

vaibby
vaibby

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

Related Questions