How to add an image when a row is selected and then remove it when it is deselected in UITableView in SWIFT

667 Views Asked by At

I'm having an issue with making an image appear when a row is selected and then making the image disappear when another row is selected. If I touch a selected row it does not get deselected – this is OK as that is the behaviour that I want. I only want the currently selected row to be deselected when I touch another row.

I am writing in Swift.

I am using Kai Engelhardt's solution to expand the selected row, as answered here.

This UIImage should appear/disappear: cellContent.ringImage.image = UIImage(named: "ring.png")

I'm guessing that my logic is wrong in the selectedCellIndexPath part below.

This is my code:

In my TVC:

class MenuViewController: UIViewController{

var selectedCellIndexPath: NSIndexPath?
let SelectedCellHeight: CGFloat = 222.0
let UnselectedCellHeight: CGFloat = 64.0

let menuItems = [
("1","test 1"),
("2","test 2"),
("3","test 3"),
("4","test 4"),
("5","test 5")]

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if tableView == menuTable {
        return menuItems.count
    } else {
            return 0}
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MenuTableViewCell
    if tableView == menuTable {
        let (my, section) = menuItems[indexPath.row]
        cell.myLabel.text = my
        cell.sectionLabel.text = section
        cell.selected = true
   }
}

func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
    if let selectedCellIndexPath = selectedCellIndexPath {
        if selectedCellIndexPath == indexPath {
            return SelectedCellHeight
        }
    }
    return UnselectedCellHeight
}

    func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
    var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MenuTableViewCell
    var cellContent = tableView.cellForRowAtIndexPath(indexPath) as! MenuTableViewCell
    let cellLabel = cellContent.sectionLabel.text

if let selectedCellIndexPath = selectedCellIndexPath {
        if selectedCellIndexPath != indexPath {
            self.selectedCellIndexPath = indexPath
            cellContent.ringImage.image = UIImage(named: "ring.png")

        } else {
            self.selectedCellIndexPath != indexPath
            cellContent.ringImage.hidden = true
              tableView.deselectRowAtIndexPath(indexPath, animated: true)
        //    cellContent.testbutton.removeFromSuperView

        }
    } else {
        selectedCellIndexPath = indexPath
        cellContent.ringImage.hidden = true
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
    tableView.beginUpdates()
    tableView.endUpdates()       
}

Your help is greatly appreciated!

Thanks

Mikee

1

There are 1 best solutions below

3
On

It seems that self.selectedCellIndexPath != indexPath does not do the deselect mark effect you want. You may try to use tableView.indexPathsForSelectedRows() to get the currently selected indexPath, compare it with the indexPath in the argument, and then complete your logic without assigning self.selectedCellIndexPath.

(Edited) As I find that you also need the varialbe self.selectedCellIndexPath to identify the height, you could try to convert it to a counter variable which counts the selected time of currently selected row. If it is odd, it is selected, while when it's even that you know you would deselect it and reset the counter varialbe to zero.

func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
    if (indexPath == tableView.indexPathsForSelectedRows()[0] && self.counter % 2 == 1) {
    return SelectedCellHeight
    }
    return UnselectedCellHeight
}