Search code examples
iosswiftuitableviewuikituislider

UISliders inside different UITableViewCells affect each other when continuous


I have made a UITableView with some cells containing UISliders. Every UISlider has a unique tag - the number of a value it represents.

When isContinuous value is set to true for them, the first and the last sliders affect each other - dragging one of them makes the same change in value on the other.
Here is how those cells are made:

class CellWithSliderValues: UITableViewCell{
    @IBOutlet var slider: UISlider! = {
        let ctrl = UISlider()
        ctrl.backgroundColor = Constants.SETTINGS_CELL_COLOR
        return ctrl
    }()
    // some labels
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        // layout
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        slider.tag = -10
        minLabel.text = nil
        maxLabel.text = nil
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
internal func makeSignalLevelCell(\*some args*\) -> UITableViewCell{
        let tag: Int
        let currValue: Float
        let minValue, maxValue: Float
        switch(kind){
        \\ set all the values above
        }
        if (numInSection == 0){
            // other cells
        } else{
            let cell = mainScreen.table.dequeueReusableCell(withIdentifier: "CellWithSliderValues") as! CellWithSliderValues
            cell.slider.maximumValue = maxValue
            cell.slider.minimumValue = minValue
            cell.slider.value = currValue
            cell.minLabel.text = Int(minValue).description
            cell.maxLabel.text = Int(maxValue).description
            cell.slider.tag = tag
            cell.slider.addTarget(self, action: #selector(sliderChange), for: .valueChanged)
            return cell
        }
@objc func sliderChange(sender: UISlider){
        guard let valueToAdjustNumber = HeatmapSettings.RangedValueOption(rawValue: sender.tag) else {print("Non-understood slider"); return}
        print (valueToAdjustNumber)
        let newValueGiven = sender.value
        switch(valueToAdjustNumber){
        \\check for validity and save changes to a different variable
        }
        sender.resignFirstResponder()
        mainScreen.table.reloadData() // beacuse we need to refresh the number in text box
    }

The first and the last sliders in the table affect each other - when one has its value adjusted, the other changes its value too. With some debug outputs - see the

print (valueToAdjustNumber)

line above - it looks like valueToAdjustNumber alternates between the one expected for the slider and the one affected by the glitch.

It is not the problem of cell reuse - I tried genereting new cells instead of reuse, and also reusing cells but recreating sliders, it did not help.

When .isContinuous is set to false for the sliders, the problem disappears.


Solution

  • Bug disappeared after reloading only one section at a time.

    mainScreen.table.reloadData() 
    

    Is made into

    mainScreen.table.reloadSections([sectionNumberToReload(value: valueToAdjustNumber)], with: .none)