rob8989
rob8989

Reputation: 91

Change image on selection in UITableViewCell(swift 3 xcode)

I have an imageView inside my tableViewCell and i would like to have its image changed on selection. This is the code I have for it:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let myCell = tableView.cellForRow(at: indexPath) as! TableCell
    myCell.resourceIcons.image = UIImage(named: "RubiusResources2")
    tableView.deselectRow(at: indexPath, animated: true)

}

The code works, but some of the other rows in a different section further down the tableView also seem change.

EDIT:

Using the comments bellow I came to the following solution:

I first created a 2D bool array to the amount of sections and rows my table had and set them all to false.

var resourceBool = Array(repeating: Array(repeating:false, count:4), count:12)

I then created an if statement to check if the array at indexPath was false or true. This would be where the states of the image would change.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let myCell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! TableCell

    if (global.resourceBool[indexPath.section][indexPath.row] == false) {
        myCell.resourceIcons.image = global.systemResourceImages[0]
    } else if (global.resourceBool[indexPath.section][indexPath.row] == true) {
        myCell.resourceIcons.image = global.systemResourceImages[1]
    }

    return myCell
}

Then, in the didSelectRow function I change the array at indexPath to true and reload the tableView data.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    global.resourceBool[indexPath.section][indexPath.row] = true
    tableView.reloadData()
    tableView.deselectRow(at: indexPath, animated: true)

}

From my understanding, the states of an object must always be in the cellForRow.

Upvotes: 2

Views: 3087

Answers (1)

Abdul91
Abdul91

Reputation: 726

One of the solution would be that you need to maintain a seperate list of rows you selected, compare them in cellForRowAt method.

Code would look something like this.

var selectedArray : [IndexPath] = [IndexPath]()

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let myCell = tableView.cellForRow(at: indexPath) as! TableCell
    myCell.resourceIcons.image = UIImage(named: "RubiusResources2")
    tableView.deselectRow(at: indexPath, animated: true)

    if(!selectedArray.contains(indexPath))
    {
        selectedArray.append(indexPath)
    }
    else
    {
        // remove from array here if required
    }
}

and then in cellForRowAt, write this code to set proper images

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        .
        .
        .

        if(selectedArray.contains(indexPath))
        {
            // use selected image
        }
        else
        {
            // use normal image
        }

        .
        .
        .
    }

Upvotes: 3

Related Questions