滚动时 tableView 单元格标签堆栈

发布于 2025-01-16 12:27:07 字数 1341 浏览 2 评论 0原文

我有一个自定义的 tableView,完全是用代码创建的。即,单元格也需要在代码中。

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


            let namelabel = UILabel()
            namelabel.frame = CGRect(x: 145, y: 10 , width: 200, height: 30 )
            namelabel.text = itemToShow.name
            namelabel.font = UIFont.boldSystemFont(ofSize: 20)
            namelabel.backgroundColor = .clear
            cell.addSubview(namelabel)

            let detailLabel = UILabel()
            detailLabel.frame = CGRect(x: 145, y: 50 , width: 200, height: 50 )
            detailLabel.text = itemToShow.detail
            detailLabel.backgroundColor = .clear
            cell.addSubview(detailLabel)

            let inventoryImage = UIImageView()
            inventoryImage.frame = CGRect(x: 10, y: 10, width: 130, height: 130)
            inventoryImage.image = UIImage(named: "emptyInventorySlot")
            cell.addSubview(inventoryImage)

        
        
        return cell
    }

它工作得很好,你可以看到它完美加载。顶部图像是负载,底部图像是滚动到底部后的图像。您可以看到文本标签似乎全部堆叠在一起。

输入图片此处描述

I have a custom tableView, entirely created in code. IE, the cells need to be in code too.

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


            let namelabel = UILabel()
            namelabel.frame = CGRect(x: 145, y: 10 , width: 200, height: 30 )
            namelabel.text = itemToShow.name
            namelabel.font = UIFont.boldSystemFont(ofSize: 20)
            namelabel.backgroundColor = .clear
            cell.addSubview(namelabel)

            let detailLabel = UILabel()
            detailLabel.frame = CGRect(x: 145, y: 50 , width: 200, height: 50 )
            detailLabel.text = itemToShow.detail
            detailLabel.backgroundColor = .clear
            cell.addSubview(detailLabel)

            let inventoryImage = UIImageView()
            inventoryImage.frame = CGRect(x: 10, y: 10, width: 130, height: 130)
            inventoryImage.image = UIImage(named: "emptyInventorySlot")
            cell.addSubview(inventoryImage)

        
        
        return cell
    }

It works great, and you can see it loads perfectly. The top image is the load, the bottom image is once I scroll to the bottom. You can see the text labels seem to all stack on top of each other.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冧九 2025-01-23 12:27:07

我不建议这样做。
最好将创建 namelabel、detailLabel 和 inventoryImage 的代码移至从 UITableViewCell 派生的 inventoryCell 类。

但你可以让它发挥作用。
由于表格单元格被重用,并且重用的单元格已经包含创建的子视图,因此您需要删除子视图或以不同的方式处理具有已创建的子视图的单元格。

您应该将标签放置在 UITableCellView 的 contentView 中。

为了让你的代码工作,你可以这样做:

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

        // remove any subviews from contentView from recycled cells 
        cell.contentView.subviews.forEach{ $0.removeFromSuperview() }

        let namelabel = UILabel()
        namelabel.frame = CGRect(x: 145, y: 10 , width: 200, height: 30 )
        namelabel.text = itemToShow.name
        namelabel.font = UIFont.boldSystemFont(ofSize: 20)
        namelabel.backgroundColor = .clear
        // add any label to contentView of the cell
        cell.contentView.addSubview(namelabel)

        let detailLabel = UILabel()
        detailLabel.frame = CGRect(x: 145, y: 50 , width: 200, height: 50 )
        detailLabel.text = itemToShow.detail
        detailLabel.backgroundColor = .clear
        // add any label to contentView of the cell
        cell.contentView.addSubview(detailLabel)

        let inventoryImage = UIImageView()
        inventoryImage.frame = CGRect(x: 10, y: 10, width: 130, height: 130)
        inventoryImage.image = UIImage(named: "emptyInventorySlot")
        // add any label to contentView of the cell
        cell.contentView.addSubview(inventoryImage)

    
    
    return cell
}

更好的是:

  • 创建一个 UITableViewCell 子类
  • ,在那里放置标签位置和配置,
  • 照顾单元格重用,重写prepareForReuse()以支持单元格重用,
  • 将此类注册为 tableView 的表视图单元格
  • 将出列的单元格转换为 UITableViewCell 子类

I would not recommend doing it this way.
It's better to move the code that creates namelabel, detailLabel and inventoryImage to an inventoryCell class derived from UITableViewCell.

But you can make it work.
Since table cells are reused and the reused cells already contain the created subviews, you need to either remove the subviews or treat cells with already created subviews differently.

And you should place your labels in the contentView of your UITableCellView.

To make your code work you can do this:

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

        // remove any subviews from contentView from recycled cells 
        cell.contentView.subviews.forEach{ $0.removeFromSuperview() }

        let namelabel = UILabel()
        namelabel.frame = CGRect(x: 145, y: 10 , width: 200, height: 30 )
        namelabel.text = itemToShow.name
        namelabel.font = UIFont.boldSystemFont(ofSize: 20)
        namelabel.backgroundColor = .clear
        // add any label to contentView of the cell
        cell.contentView.addSubview(namelabel)

        let detailLabel = UILabel()
        detailLabel.frame = CGRect(x: 145, y: 50 , width: 200, height: 50 )
        detailLabel.text = itemToShow.detail
        detailLabel.backgroundColor = .clear
        // add any label to contentView of the cell
        cell.contentView.addSubview(detailLabel)

        let inventoryImage = UIImageView()
        inventoryImage.frame = CGRect(x: 10, y: 10, width: 130, height: 130)
        inventoryImage.image = UIImage(named: "emptyInventorySlot")
        // add any label to contentView of the cell
        cell.contentView.addSubview(inventoryImage)

    
    
    return cell
}

Better would be:

  • create a UITableViewCell subclass
  • place your label placement and configuration there
  • take care of cell reuses, override prepareForReuse() to support cell reuse
  • register this class as a table view cell for your tableView
  • cast your dequeued cell to your UITableViewCell subclass
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文