Search code examples
iosswiftuitableviewcustom-cell

UITableViewCell is repeating after every 5th cell (Before you mark as duplicate kindly read the whole quest )


(Before you mark as duplicate you have to read the whole question and I am posting this cause I din't found the relevant and proper solution also need the solution in swift)

I have created one demo project and load and displayed name and area from array on custom cell. I have noticed that after every 5th cell means 6th row is repeating with contents of 0th cell for e.g.

the demo code is given below

class demoTableCell: UITableViewCell {
    @IBOutlet var name : UILabel!
    @IBOutlet var area : UILabel!
}

extension ViewController:UITableViewDelegate, UITableViewDataSource{
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.arrDemo.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        var cell : demoTableCell = demoTable.dequeueReusableCell(withIdentifier: cellIdentifier)! as! demoTableCell

            cell.name.text = (arrDemo.object(at: indexPath.row) as! NSDictionary).value(forKey: "Name") as? String
            cell.area.text = (arrDemo.object(at: indexPath.row) as! NSDictionary).value(forKey: "Area") as? String

            if indexPath.row == 0{
                cell.name.isHidden = true
            }

        return cell
    }

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

    }
}

As I hide the first label on 0th cell so I found that 6th row is also effected with implemented functionality of 0th cell. It means that also hide label1 of every 6th cell as I have attached the screenshot below so you can get the exact issue (This issue happened only if table view is scrollable)

enter image description here enter image description here

As I have try to solve this issue from this link also but facing the same issue and cannot find the proper solution, and I am stuck here.


Solution

  • Remember - the cells are being reused.

    You hide the cell, but you never explicitly unhide the cell

    When you come to row 6, you are re-using the cell that was at row 0, and isHidden = true

    All you need to do is extend your check, and hide the rows that you need to be hidden, and explicitly show the cells that you need to see. If you also have a moving banner that you add - you will also need to check to see if it's been loaded, and remove it if not required. Remember - it may not be row 6 - that's just how it works out with the current screensize

    If you do have significant differences between the cells you want to use, you might be better using two different classes - and then you don't have to think about hiding labels

    class demoTableCell: DemoTableCellNormalRow {
        @IBOutlet var name : UILabel!
        @IBOutlet var area : UILabel!
    }
    
    class demoTableCell: DemoTableCellFirstRow {
        @IBOutlet var area : UILabel!
        @IBOutlet var movingBannerView : LCBannerView!
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
    
        if row == 0 {
            var cell : demoTableCell = demoTable.dequeueReusableCell(withIdentifier: cellIdentifier)! as! DemoTableCellFirstRow
    
            cell.area.text = (arrDemo.object(at: indexPath.row) as! NSDictionary).value(forKey: "Area") as? String
    
            // populate the bannerview which already exists, or create a new one
    
            return cell
        } else {
            var cell : demoTableCell = demoTable.dequeueReusableCell(withIdentifier: cellIdentifier)! as! DemoTableCellNormalRow
    
            cell.name.text = (arrDemo.object(at: indexPath.row) as! NSDictionary).value(forKey: "Name") as? String
            cell.area.text = (arrDemo.object(at: indexPath.row) as! NSDictionary).value(forKey: "Area") as? String
    
            return cell
        }
    }