Search code examples
iosswiftuitableviewuiswitch

UISwitch is changing state on other cell when scroll


My tableview looks like this

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
    return cell
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 200
}

And my tableviewcell looks like this

class Cell: UITableViewCell {

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

When I change switch state on any cell and scroll. The switch for another cell periodically have state changed on scroll for other cells. Please help

layout of uiswitch


Solution

  • You need to have data array with state for every switch and in your didSelect method change data model for switch then in cellForRow at get switch state from array and your viewController need to be SwitchControlDelegate

    class UIViewController:SwitchControlDelegate{
    
        var array = [Bool](count: 200, repeatedValue:false)
    
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
        cell.switchControl.isOn = array[indexPath.row]
        cell.switchDelegate = self
        cell.index = indexPath.row
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 200
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        array[indexPath.row] = !array[indexPath.row]
    }
    
    func switchChangeStateWithIndex(index:Int){
        array[index] = !array[index]
    }
    

    This will change switch state when you click on cell , if you need to change state when change switch control you will need delegate to update data model in viewController

    In your cell file:

        protocol SwitchControlDelegate: class {
            func switchChangeStateWithIndex(index:Int)
        }
    
        class Cell: UITableViewCell {
    
            var index:Int = 0
            weak var switchDelegate: SwitchControlDelegate?
            override func awakeFromNib() {
                super.awakeFromNib()
                // Initialization code
            }
    
            override func setSelected(_ selected: Bool, animated: Bool) {
                super.setSelected(selected, animated: animated)
    
                // Configure the view for the selected state
            }
    
            @IBAction func valueChanged(_ sender: AnyObject) {
                 switchDelegate?.switchChangeStateWithIndex(index:index)
            }
    
    }
    

    You need to match action value change from your switch control with this function valueChanged , so every time when you change switch state cell need to call func value Changeed