-1

Hi everyone!)) Perhaps someone can suggest a solution. I'm just starting to learn Swift, writing an application for myself. I launch the project (cmn + R ) in the simulator, everything is ok. When you use scrolling again for the 2nd time to see the last cell of the table, you can see that the text of the cell is overwritten and laid down as a layer on top. ......The first and second screenshots show the ideal expected state. The third and fourth screenshots show how the defect looks like when I used scrolling 2 times. write code without StoryBoard, Version 14.0.1 (14A400) (( the ideal expected state...The ideal expected state... the ideal expected state...the ideal expected state... how the defect looks like when I used scrolling...Defect in the 1st top line (cell)... how the defect looks like when I used scrolling...Defect in the last line (cell)... P.S. The cell contains 5 UILabel which represent the data taken from the array.

I don't know what to do, what could it be(

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: tabViewCell, for: indexPath)
    cell.backgroundColor        = .systemGray5
    cell.layer.cornerRadius     = cornerRadiusCell
    cell.layer.borderWidth      = 2
    cell.layer.borderColor      = CGColor.init(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
    cell.accessoryType          = .detailButton
    cell.tintColor              = colorTextinCell
    
    let labelIdProd           = UILabel(frame: CGRect(x: 25, y: 7, width: 40, height: 30))
   
    let numbId: String = String(allItems[indexPath.section].listP[indexPath.row].id)
    var numbIdForCell: String {
        get {
            if allItems[indexPath.section].listP[indexPath.row].id < 10 {
                return "00\(allItems[indexPath.section].listP[indexPath.row].id)"
            }
            if allItems[indexPath.section].listP[indexPath.row].id >= 10 {
                return "0\(allItems[indexPath.section].listP[indexPath.row].id)"
            }
                return "\(allItems[indexPath.section].listP[indexPath.row].id)"
            }
        set {
        }
    }

    numbIdForCell = numbId
    labelIdProd.text          = numbIdForCell
    labelIdProd.textColor     = colorTextinCell
    cell.addSubview(labelIdProd)
    
    let labelTextProd           = UILabel(frame: CGRect(x: 75, y: 7, width: 85, height: 30))
    labelTextProd.textColor     = colorTextinCell
    labelTextProd.text          =  String(allItems[indexPath.section].listP[indexPath.row].namePrdct)
    cell.addSubview(labelTextProd)
    
    let labelAmountProd           = UILabel(frame: CGRect(x: 170, y: 7, width: 40, height: 30))

    let numb = allItems[indexPath.section].listP[indexPath.row].amoutn
    labelAmountProd.text          = String(numb)
    labelAmountProd.textColor     = colorTextinCell
    cell.addSubview(labelAmountProd)
    
    let labelPriceLVL2Prod           = UILabel(frame: CGRect(x: 220, y: 7, width: 40, height: 30))

    labelPriceLVL2Prod.text          = String(format: "%.1f", allItems[indexPath.section].listP[indexPath.row].priceLevel2)
    labelPriceLVL2Prod.textColor     = colorTextinCell
    cell.addSubview(labelPriceLVL2Prod)
    
    let labelAmountAndPriceVLV2Prod           = UILabel(frame: CGRect(x: 270, y: 7, width: 60, height: 30))

    labelAmountAndPriceVLV2Prod.text          = String(format: "%.1f", Double(allItems[indexPath.section].listP[indexPath.row].amoutn) * allItems[indexPath.section].listP[indexPath.row].priceLevel2)
    labelAmountAndPriceVLV2Prod.textColor     = colorTextinCell
    cell.addSubview(labelAmountAndPriceVLV2Prod)

    return cell
}
  • 1
    You need to post relevant code for anyone to help properly. But most likely you are not properly handling cell reuse and keep adding labels to your cell. – HangarRash Nov 06 '22 at 21:11
  • Hello Hangar Rush! Should I post all the code? or some part of code?! Lots of code ((. And never heard anything like that about "are not properly handling cell reuse and keep adding labels to your cell" But it sounds like the problem is there. Responsible for this UIScrollView? – Vladislav Zhelezniak Nov 06 '22 at 21:50
  • Start with the `cellForRowAt` method of your table view data source. – HangarRash Nov 06 '22 at 23:10
  • Ook I did, .......so ashamed of my code) – Vladislav Zhelezniak Nov 07 '22 at 03:33

1 Answers1

0

Cells get reused as you scroll. Your cellForRowAt method doesn't take that into account. It happily adds more and more labels to each cell as you scroll resulting in overlapping information.

The best solution is to create a custom UITableViewCell class that sets up its own views. It should only provide properties for setting its data.

Then in cellForRowAt you simply dequeue the cell, assign data to the cell for the given indexPath, and that's it. The custom cell class will then update its existing labels (and other subviews if needed) with the new data. The custom cell class only creates its subviews once.

An even better approach is the new contentConfiguration approach added in iOS 14. You still end up with a custom class that sets up the cell so cellForRowAt has no responsibility for setting up the cell, only providing data for the row to the cell.

See how to use iOS 14 cell content configurations in general? for a good example of using contentConfiguration for creating and setting up a custom cell.

HangarRash
  • 7,314
  • 5
  • 5
  • 32
  • Hello HangarRash! Thanks for the answer, I tried to analyze the problem, only I understood that it had something to do with scrolling the table. I thought it was solved by default under the hood XCode. Today I began to get acquainted with the "contentConfiguration" I met this problem because I wrote the wrong code and there are more cells than fit on the screen? – Vladislav Zhelezniak Nov 08 '22 at 15:31