Search code examples
swiftuitableviewdidselectrowatindexpath

While scrolling tableview Unnecessary check mark showing in tableview why? swift


code:

I have added check box in my tableview cell design in storyboard

code: if there are 8 cells then if i select first cell then got blue_tick image in first cell and why in 5th cell also got blue_tick.. here i have selected only first cell..

in the same way if i select 2nd cell then 6th cell also got blue_tick why? where am i wrong

var selectedArray:[Int] = []

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

if tableView == self.tableView{
    
    let cell:PaymentCell = tableView.cellForRow(at: indexPath) as! PaymentCell
    if let indexData = eventListData?.result?.events?[indexPath.row] {
        
        if let index = selectedArray.firstIndex(of: indexData.id ?? 0) {
            
            cell.checkImg.image = UIImage(named: "checkbox_inactive")
            selectedArray.remove(at: index)
            
        } else {
            selectedArray.append(indexData.id ?? 0)
            cell.checkImg.image = UIImage(named: "blue_tick")
        }
    }
}
}

why for selecting one cell every 5th cell un unnecessarily also got blue_tick.. please do guide me got stuck here from long.. but didn't get solution till now

in cellForRowAt handled like this

var isfromDetails = false

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

let cell = tableView.dequeueReusableCell(withIdentifier: "PaymentCell", for: indexPath) as! PaymentCell

let indexData = eventListData?.result?.events?[indexPath.row]
cell.titleLbl.text = indexData?.event_title
cell.addressLbl.text = indexData?.event_venue

var floatVal: Float?
if let standardRate = indexData?.ticket_price,
   let convValue = eventListData?.result?.conversion_factor {
    let priceVal = Float(standardRate)
    let convVal = Float(convValue)
    
    floatVal = (priceVal * convVal!)
    
    if let floatVal = floatVal {
        let formatter = NumberFormatter()
        formatter.maximumFractionDigits = 2
        formatter.roundingMode = .down
        let roundedValue1: String = formatter.string(from: floatVal as NSNumber) ?? ""
        
        cell.priceLbl.text = "\(eventListData?.result?.user_curreny?.symbol ?? "GBP") \(roundedValue1)"
        
    } else {
        cell.priceLbl.text = "N/A"
    }
}
let bannerImage = indexData?.event_thumbnail ?? ""
cell.bannerImg.getImage(subUrl: eventListImageBaseUrl, withImagePath: bannerImage, placeHolder: #imageLiteral(resourceName: "icon8"))
cell.bannerImg.contentMode = .scaleAspectFit

if isfromDetails{
    let id = indexData?.id ?? 0
    if selectedArray.contains(id){
        cell.checkImg.image = UIImage(named: "blue_tick")
    }else{
        cell.checkImg.image = UIImage(named: "checkbox_inactive")
    }
}
return cell
}

class EventListCell: UITableViewCell {

@IBOutlet weak var checkImg: UIImageView!
override func awakeFromNib() {
    selectionStyle = .none
    super.awakeFromNib()
}
}

how to solve this unnecessary image in unwanted cell,

Note: if i put break point and debug then in cellForRow its not going inside if isfromDetails{ still blue_tick shoes why? and if i comment that code in cellForRow still blue_tick showes why?. And here id is not appending in arrSelectedRowsBuy but just blue_tick image showing in cell.

where am i wrong. please do guide me


Solution

  • The reason is quite clear:

    Cells are reused, but – for performance reasons - the states of the UI elements are not reset to a default state. Therefore you have to make sure that all UI elements are set to a defined state in cellForRowAt.

    In this case if isfromDetails is false the state of cell.checkImg.image is undefined. A reasonable solution is to merge all if statements into one.

    The cell will show a checkmark if isfromDetails is true, id does exist and selectedArray contains the id

    if isfromDetails, let id = indexData?.id, selectedArray.contains(id) {
       cell.checkImg.image = UIImage(named: "blue_tick")
    } else {
       cell.checkImg.image = UIImage(named: "checkbox_inactive")
    }
    

    I highly recommend to drop selectedArray and maintain the selected state in the data model.

    And why ist everything optional (eventListData?.result?.events?[indexPath.row])? The data source of an existing non-optional table view should be non-optional.