Selected button of a UITableViewCell get disappear when scrolling

I’m working on a project coded in swift 3 and I have a UIButton inside a UITableViewCell where the image changes once the button is tapped. Though the selected buttons get selected as intended, once the UITableview scrolls the selected images gets disappear since the cells are been reused. As I’m new to programming having troubles of writing the logic. Help would much appreciate the code as bellow.

CellFoRow

  • Cocoa singleton and shared instances
  • UIDatePicker with 15m interval but always exact time as return value
  • How to build project with unsupported class (new feature) in xcode and swift
  • Swift: How to get everything after a certain set of characters
  • How do I change the color of the status bar in an iPhone app?
  • NSMutableArray Difficulty
  •      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
             let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    
            //Button_Action
             addSongButtonIdentifier(cell: cell, indexPath.row)
    
       }
    

    This is where the cell is been created.

    func addSongButtonIdentifier(cell: UITableViewCell, _ index: Int) {
        let addButton = cell.viewWithTag(TABLE_CELL_TAGS.addButton) as! UIButton
    
        //accessibilityIdentifier is used to identify a particular element which takes an input parameter of a string
    
        //assigning the indexpath button
        addButton.accessibilityIdentifier = String (index)
       // print("visible Index:",index)
        print("Index when scrolling :",addButton.accessibilityIdentifier!)
    
    
               addButton.setImage(UIImage(named: "correct"), for: UIControlState.selected)
    
    
               addButton.setImage(UIImage(named: "add_btn"), for: UIControlState.normal)
    
    
        addButton.isSelected = false
        addButton.addTarget(self, action: #selector(AddToPlaylistViewController.tapFunction), for:.touchUpInside)
    
    
    }
    

    the tap function

    func tapFunction(sender: UIButton) {
        print("IndexOfRow :",sender.accessibilityIdentifier!)
        // if let seporated by a comma defines, if let inside a if let. So if the first fails it wont come to second if let
    
    
        if let rowIndexString =  sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) {
        self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]//toggle the state when tapped multiple times
        }
        sender.isSelected = !sender.isSelected //image toggle
        print(" Array Data: ", self.sateOfNewSongArray)
    
        selectedSongList.removeAll()
    
        for (index, element) in self.sateOfNewSongArray.enumerated() {
            if element{
                print("true:", index)
    
                selectedSongList.append(songDetailsArray[index])
    
                print("selectedSongList :",selectedSongList)
            }
        }
    
    
    }
    

    2 Solutions Collect From Internet About “Selected button of a UITableViewCell get disappear when scrolling”

    You have this code addButton.isSelected = false which is causing the problem because I believe you are calling the function addSongButtonIdentifier inside tableView delegate method, you should not set all those property inside tableView delegate.

    Instead you should do it initially and only once for each of your cell like either in storyboard itself or by providing a model to cell class.

    You need to maintain the button selection status at the controller level. You need to make changes to the model that you are using to configure your tableview.

    I have created a similar scenario. I have used an array selectionStatusArray to maintain the button’s selection status.

    Example:

    1. UIViewController containing UITableView

    class ViewController: UIViewController, UITableViewDataSource
    {
        @IBOutlet weak var tableView: UITableView!
        var selectionStatusArray = [false, false, false, false, false] //Array that maintains the button selection status
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
        {
            return selectionStatusArray.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
        {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
            addSongButtonIdentifier(cell: cell, indexPath.row)
            return cell
        }
    
        func addSongButtonIdentifier(cell: TableViewCell, _ index: Int)
        {
            cell.addButton.tag = index
            cell.addButton.isSelected = selectionStatusArray[index]
            cell.tapHandler = {
                self.selectionStatusArray[$0] = cell.addButton.isSelected
            }
        }
    }
    

    2. Custom UITableViewCell

    class TableViewCell: UITableViewCell
    {
        @IBOutlet weak var addButton: UIButton!
        var tapHandler: ((Int)->())?
    
        @IBAction func tapFunction(_ sender: UIButton)
        {
            sender.isSelected = !sender.isSelected
            tapHandler?(sender.tag)
        }
    }
    

    You can configure the UITableViewCell according to your requirements.