Benjamin RD
Benjamin RD

Reputation: 12034

Add view dynamically to cells produce issues in table

I have this function:

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

        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!

        let label = UILabel(frame: CGRect(x: 100, y: 14, width: 400, height: 30))
        label.text = "\(data[indexPath.row])"
        label.tag = indexPath.row
        cell.contentView.addSubview(label)

        return cell
    }

Well, with this function I'm adding a list of rows dynamically. Why dynamically? Because, the number of columns depends of the data. Don't take focus on that.

The list has 244 elements. The result is displayed ok, but once I started scrolling, I get this:

enter image description here

How I can add elements dynamically without get this error?

Upvotes: 1

Views: 362

Answers (3)

a.masri
a.masri

Reputation: 2469

UITableview create 10 cell at scroll down recreate cell view

You can using cell.contentView.removeFromSuperview() before cell.contentView.addSubview(label) or using cell.textLabel?.text

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

        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
        cell.contentView.removeFromSuperview()
        let label = UILabel(frame: CGRect(x: 100, y: 14, width: 400, height: 30))
        label.text = "\(data[indexPath.row])"
        label.tag = indexPath.row
        cell.contentView.addSubview(label)

        return cell
    }

Note This solution will delete All subview in cell

Upvotes: -1

Benjamin RD
Benjamin RD

Reputation: 12034

I found a solution, hope this works to you!!!

You have to add to your cellForRowAt this code:

for item in cell.contentView.subviews
    {
        item.removeFromSuperview()
    }

Just after to get the cell.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!

    for item in cell.contentView.subviews
    {
        item.removeFromSuperview()
    }

    let label = UILabel(frame: CGRect(x: 100, y: 14, width: 300, height: 30))
    label.text = "\(data[indexPath.row])"
    label.tag = indexPath.row

    let btn = UIButton(type: UIButtonType.custom) as UIButton
    btn.backgroundColor = UIColor.red
    btn.setTitle("boton", for: .normal)
    btn.frame = CGRect(x:0, y:5, width: 80, height:40)
    //btn.addTarget(self, action: "buttonPressed:", for: UIControlEvents.touchUpInside)
    btn.tag = indexPath.row
    cell.contentView.addSubview(btn)
    cell.contentView.addSubview(label)

    cell.tag = indexPath.row

    return cell
}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318854

Cells get reused. You keep adding more and more labels to each cell.

The proper solution is to create a custom cell class that contains the desired label. Then simply set that label's text in cellForRowAt. Don't create and add subviews in cellForRowAt.

But keep in mind that you may just want to use the provided textLabel property of UITableViewCell. No need for a custom cell or your own label.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
    cell.textLabel?.text = "\(data[indexPath.row])"

    return cell
}

Upvotes: 2

Related Questions