发生重用时,为什么UIStackView中的UILabel会失去高度?

问题描述 投票:1回答:1

当单元被重用时,UIStackView中的UILabel开始失去大小。它可能与什么有关。对于表格,在UITableView.automaticDimension中设置单元格高度。

我不知道这与重用有什么关系,因为我使用prepareForReuse。

class SalesPointTableViewCell: UITableViewCell {

private var nameLabel = UILabel()

private var someView: UIStackView = {
    $0.distribution = .fill
    $0.translatesAutoresizingMaskIntoConstraints = false
    $0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)

    return $0
}(UIStackView())

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    translatesAutoresizingMaskIntoConstraints = false
    contentView.translatesAutoresizingMaskIntoConstraints = false
    contentView.addSubview(nameLabel)
    contentView.addSubview(someView)
    nameLabel.snp.makeConstraints {
        $0.left.top.equalToSuperview()
    }
    someView.snp.makeConstraints {
        $0.left.right.width.equalToSuperview()
        $0.top.equalTo(nameLabel.snp.bottom)
    }
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
    super.prepareForReuse()
    nameLabel.text = nil
    someView.arrangedSubviews.forEach {$0.removeFromSuperview()}
}

func configure(name: String, points: [String]) {
    self.nameLabel.text = name
    points.forEach { pointName in
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.numberOfLines = 1
        label.text = pointName
        self.someView.addArrangedSubview(label)
        label.sizeToFit()
    }
}
}
swift uitableview uilabel uistackview
1个回答
0
投票

耦合事物...

  • 请勿在.translatesAutoresizingMaskIntoConstraints或其cell上设置.contentView
  • 您正在为堆栈视图设置leadingtrailing约束,因此无需设置其width
  • 您缺少bottom约束

尝试一下:

class SalesPointTableViewCell: UITableViewCell {

    private var nameLabel = UILabel()

    private var someView: UIStackView = {

        $0.distribution = .fill

        // add a little spacing between arranged subviews so we can see them
        $0.spacing = 4

        $0.translatesAutoresizingMaskIntoConstraints = false
        $0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)

        return $0
    }(UIStackView())

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        // no no no
        //translatesAutoresizingMaskIntoConstraints = false

        // no no no
        //contentView.translatesAutoresizingMaskIntoConstraints = false

        contentView.addSubview(nameLabel)
        contentView.addSubview(someView)

        nameLabel.snp.makeConstraints {
            $0.left.top.equalToSuperview()
        }

        // you're missing a bottom constraint
        //someView.snp.makeConstraints {
        //  $0.left.right.width.equalToSuperview()
        //  $0.top.equalTo(nameLabel.snp.bottom)
        //}

        someView.snp.makeConstraints {
            // costraining left and right, so no need for width
            //  $0.left.right.width.equalToSuperview()
            $0.left.right.equalToSuperview()

            $0.top.equalTo(nameLabel.snp.bottom)

            // need to add a bottom constraint
            $0.bottom.equalToSuperview()
        }

        // give nameLabel a cyan background to make it easy to see the frame
        nameLabel.backgroundColor = .cyan
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func prepareForReuse() {
        super.prepareForReuse()
        nameLabel.text = nil
        someView.arrangedSubviews.forEach {$0.removeFromSuperview()}
    }

    func configure(name: String, points: [String]) {
        self.nameLabel.text = name
        points.forEach { pointName in
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false

            // give labels a green background to make it easy to see the frames
            label.backgroundColor = .green
            label.textAlignment = .center

            label.numberOfLines = 1
            label.text = pointName
            self.someView.addArrangedSubview(label)

            // sizeToFit is not needed
            //label.sizeToFit()
        }
    }
}

class SalesTableViewController: UITableViewController {

    var theData: [[String]] = [[String]]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(SalesPointTableViewCell.self, forCellReuseIdentifier: "SPCell")

        // generate 50 "sales points"
        // each "sales point" will have 1, 2 or 3 labels
        for i in 1...50 {
            let n = Int.random(in: 1...3)
            var a: [String] = [String]()
            for j in 1...n {
                a.append("Point: \(i) / \(j)")
            }
            theData.append(a)
        }

    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theData.count
    }

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "SPCell", for: indexPath) as! SalesPointTableViewCell

        let a = theData[indexPath.row]

        cell.configure(name: "Test \(indexPath.row)", points: a)

        return cell

    }

}

结果:

enter image description here

并且,在滚动之后,您可以看到它们已被重用:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.