【问题标题】:UITableViewCell with UIStackView with varying items?UITableViewCell 与 UIStackView 与不同的项目?
【发布时间】:2020-08-14 05:54:10
【问题描述】:

我有一个带有自定义单元格的典型 UITableView。所有单元格都属于同一类型 - 一个 UIStackView 包含相同类型的视图,但数量不同。

尝试使用一个单元格-删除-添加内部视图很慢。

尝试为不同数量的子视图创建不同的单元格:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let row = rows[indexPath.row]
        let CellIdentifier = "CellIdentifier\(row.subrows.count)"
        var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? CustomCell
        if cell == nil {
            tableView.register(UINib(nibName: "WTRemindersTableViewCell", bundle: nil), forCellReuseIdentifier: CellIdentifier)
            cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? CustomCell
            for _ in row.subrows {
                let v = Bundle.main.loadNibNamed("CustomInnerView", owner: self, options: nil)?.first as! WTRemindersCellLineView
                cell!.stackView.addArrangedSubview(v)
            }
        }
        return cell!
    }

但它似乎只注册了一个没有子视图的单元格,并且使用不同的单元格标识符没有意义(因为每次您都需要手动添加 stackview 子视图)。

如何解决这个问题?

已编辑

为单元格添加代码

class CustomCell: UITableViewCell {
    @IBOutlet var boxView: UIView!
    @IBOutlet var imgView: UIImageView!
    @IBOutlet var lblTitle: UILabel!
    @IBOutlet var lblSubtitle: UILabel!
    @IBOutlet var dashedView: WTDashedView!
    @IBOutlet var stackView: UIStackView!
    
    weak var delegate: CustomCellDelegate?
    var index: Int!
    
    lazy var onceDraw: () = {
        boxView.layer.applySketchShadow()
    }()
    
    override func awakeFromNib() {
        super.awakeFromNib()
        boxView.layer.cornerRadius = 19
        imgView.layer.cornerRadius = 12
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        _=onceDraw
    }
    
    @IBAction func btnDotsClicked(_ sender: Any) {
        delegate?.btnDotsClicked(at: index)
    }
}

【问题讨论】:

  • 从几个方面来说,这是一个非常糟糕的方法。你永远不应该(好吧,永远不要说永远,但是)在cellForRowAt 中的单元格中添加子视图——你应该在你的单元格类中拥有所有这些逻辑,并告诉你的单元格进行自我配置。您也不应该在cellForRowAt 中注册单元类。这将有助于了解您的“CustomInnerView”中的内容,以便为您提供更好的建议。
  • @DonMag CustomInnerView 只包含一组简单的图像、标签和一个按钮。内部元素使用简单的约束相互链接。我同意这可能是一种不好的方法,所以我问是否有另一种更好的解决方案
  • 编辑您的问题并包含CustomCell 课程的代码。
  • @DonMag 好的,为我的单元添加了代码。没什么特别的
  • 您的数据是否会有有限数量的“子行”?也就是说,您可能有 100 行,但每行最多有 5 个“子行”?或者可能有一些可能有 20 个子行?

标签: ios swift uitableview uistackview varying


【解决方案1】:

首先,您应该在viewDidLoad 中注册您的手机。请注意,我不确定您的笔尖的名称,因此请务必根据您的需要进行调整。

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.register(
        UINib(nibName: "CustomCell", bundle: nil),
        forCellReuseIdentifier: "CustomCell"
    )
}

很难说出您在 cellForRowAt 方法中所做的事情,但这可以解决问题。单元格被重复使用,因此请确保删除任何剩余的排列子视图。如果你这样做,你应该不会有任何性能问题:

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

    let row = rows[indexPath.row]

    cell.stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
    for _ in row.subrows {
        cell.stackView.addArrangedSubview(cellView())
    }

    return cell
}

这只是实例化视图的一个小辅助方法:

func cellView() -> WTRemindersCellLineView {
    return Bundle.main.loadNibNamed(
        "WTRemindersCellLineView", owner: nil, options: nil
        )?.first as! WTRemindersCellLineView
}

【讨论】:

  • 我找到了一个更好的解决方案,它只在必要时添加和删除子视图。这是可能的,因为所有这些子视图都属于同一类型(它们的数量仅不同)。而且我对各种子视图计数使用不同的单元格标识符 - 它不允许避免额外的添加/删除子视图操作,但至少显着减少了它们的计数。关于您的cellView() - 您应该提到它仅适用于单个单元格标识符。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 2016-08-10
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 2018-03-28
相关资源
最近更新 更多