Home > other >  TableView Cells changing on reload and not displaying correct content | Swift
TableView Cells changing on reload and not displaying correct content | Swift

Time:12-08

I have a tableview that loads custom cells from a JSON array. I noticed on the first load the cells look perfectly fine. On the second load (pull to refresh) the cells are no longer following the design logic expressed in cellForRowAt - instead random cells will start displaying the color meant for other cells and images meant to be hidden.

An example of the logic failing on reload is the UIImage named "fGlyph" is being displayed where item.type == "locate" then after a refresh the tableview will display the UIImage on a completely incorrect cell.

Code so far:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! routeCell
    let item = sections[indexPath.section].items[indexPath.row]
    structure = sections[indexPath.section].items
    cell.circularView.layer.removePulses()
    tableView.backgroundColor = .tertiarySystemGroupedBackground
    cell.customerLabel.text = "\(item.name)"
    cell.addressLabel.text = "\(item.address)"
    cell.vistedLabel.text = "\(item.time)"
    
    //Round Corners of stopnumview
    cell.circularView.layer.cornerRadius = cell.circularView.frame.size.width/2
    
    
    //Setting Images
    if item.type == "locate" {
        cell.stopnumLabel.text = ""
        cell.cellImage.image = UIImage(named: "fGlyph")
    } else {
        cell.stopnumLabel.text = "\(item.stoporder)"
    }
    
    cell.vistedLabel.textColor = UIColor(red: 0.78, green: 0.78, blue: 0.78, alpha: 1.00)
    cell.completedLabel.isHidden = true
    cell.completedCheck.isHidden = true
    
    //Stop Active Logic
    switch item.stopactive {
    case 0:
        //grey - not started
        cell.circularView.backgroundColor = UIColor(red: 0.48, green: 0.48, blue: 0.50, alpha: 1.00)
    case 1:
        //green - in progress
        cell.circularView.backgroundColor = UIColor(red: 0.33, green: 0.73, blue: 0.33, alpha: 1.00)
        cell.timeLabel.textColor = UIColor(red: 0.33, green: 0.73, blue: 0.33, alpha: 1.00)
        
    case 2:
        //pink - completed
        cell.timeLabel.text = ""
        cell.addressLabel.text = ""
        cell.circularView.backgroundColor = UIColor(red: 0.23, green: 0.32, blue: 0.59, alpha: 1.00)
        
        
        //purple color
        cell.vistedLabel.textColor = UIColor(red: 0.33, green: 0.73, blue: 0.33, alpha: 1.00)
        cell.vistedLabel.alpha = 0.5
        cell.completedLabel.textColor = UIColor(red: 0.33, green: 0.73, blue: 0.33, alpha: 1.00)
        cell.completedLabel.isHidden = false
        cell.completedCheck.isHidden = false
    default:
        //default color
        cell.circularView.backgroundColor = UIColor(red: 0.48, green: 0.48, blue: 0.50, alpha: 1.00)
    }
    
    return cell
    
}

This is how the data is loaded - this is also the function used for refreshes:

private func fetchJSON() {
    guard let url = URL(string: "test.com")
    else { return }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = "1".data(using: .utf8)
    
    URLSession.shared.dataTask(with: request) { [self] data, _, error in
        guard let data = data else { return }
        
        do {
            let decoder = JSONDecoder()
            self.structure.sort { $0.rdate > $1.rdate }
            let res = try decoder.decode([rStructure].self, from: data)
            let grouped = Dictionary(grouping: res, by: { $0.routedate })
            _ = grouped.keys.sorted()
            sections = grouped.map { rSections(date: $0.key, items: $0.value) }
            .sorted { $0.date > $1.date }
            print(sections.map(\.date))
            DispatchQueue.main.async {
                self.tableView.reloadData()
                print("TableView Loaded")
            }
        }
        catch {
            print(error)
        }
    }.resume()
    
}

CodePudding user response:

in tableView Cell use below code

override func prepareForReuse() {
    self.cellImage.image = UIImage(named: "")
}

or use cell.cellImage.image = UIImage(named: "") in else block

   //Setting Images
    if item.type == "locate" {
        cell.stopnumLabel.text = ""
        cell.cellImage.image = UIImage(named: "fGlyph")
    } else {
        cell.cellImage.image = UIImage(named: "")
        cell.stopnumLabel.text = "\(item.stoporder)"
    }

CodePudding user response:

In tableview, cells are reused instead of recreated. So you need to reset cell parameters before reuse. Otherwise old data will show up in unexpected places. Below is the function to do that

override func prepareForReuse() {
    self.cellImage.image = UIImage(named: "")
}
  • Related