UITableViewCell 中带有多行标签的 UIStackView 高度不正确

Posted

技术标签:

【中文标题】UITableViewCell 中带有多行标签的 UIStackView 高度不正确【英文标题】:UIStackView with multiline label in a UITableViewCell incorrect height 【发布时间】:2019-05-16 10:25:51 【问题描述】:

我有一个表格视图,其中每个单元格显示一个可选标题和一个多行副标题。我希望单元格能够自行调整大小(即与字幕一起增长,但尽可能保持紧凑)。为此我使用tableView.rowHeight = UITableView.automaticDimension

我遇到的问题是,在有标题的单元格中,字幕周围有很多垂直间距。

没有标题的单元格被正确压缩。此外,当我重新加载表格视图时,所有布局都变得正确。

预期行为

实际行为

单元格基本上有一个UIStackView 固定在单元格的contentView 上。

import UIKit

public class TableViewCellSubtitle: UITableViewCell 

    private lazy var labelStack: UIStackView = 
        let labelStack = UIStackView()
        labelStack.alignment = .fill
        labelStack.distribution = .fillProportionally
        labelStack.axis = .vertical
        return labelStack
    ()

    private lazy var titleLabel: UILabel = 
        let titleLabel = UILabel()
        titleLabel.backgroundColor = UIColor.blue.withAlphaComponent(0.3)
        return titleLabel
    ()

    private lazy var subtitleLabel: UILabel = 
        let subtitleLabel = UILabel()
        subtitleLabel.numberOfLines = 0
        subtitleLabel.backgroundColor = UIColor.green.withAlphaComponent(0.3)
        return subtitleLabel
    ()

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

        setupUI()
        setupConstraints()
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    private func setupUI() 

        contentView.addSubview(labelStack)
        labelStack.translatesAutoresizingMaskIntoConstraints = false
        labelStack.addArrangedSubview(titleLabel)
        labelStack.addArrangedSubview(subtitleLabel)

    

    private func setupConstraints() 
        NSLayoutConstraint.activate([
                labelStack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
                labelStack.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12),
                contentView.bottomAnchor.constraint(equalTo: labelStack.bottomAnchor, constant: 12),
                contentView.trailingAnchor.constraint(equalTo: labelStack.trailingAnchor, constant: 16)
            ])
    

    public func setup(title: String?, subtitle: String) 
        titleLabel.text = title
        if title == nil 
            labelStack.removeArrangedSubview(titleLabel)
            titleLabel.removeFromSuperview()
        
        subtitleLabel.text = subtitle
    

我尝试将内容拥抱设置在字幕上

subtitleLabel.setContentHuggingPriority(.required, for: .vertical)

但这会使标题增长:

如果我将其设置为两者:

titleLabel.setContentHuggingPriority(.required, for: .vertical)
subtitleLabel.setContentHuggingPriority(.required, for: .vertical)

变成了

在所有情况下,如果我重新加载单元格或表格视图,布局将变得正确(此处为单元格点击):

我知道我可以在不使用堆栈视图的情况下布局单元格,但我的实际实现有点复杂

【问题讨论】:

检查 UIStackView 属性,检查分布 【参考方案1】: 尝试使用填充而不是按比例填充 或者尝试设置 label.sizeToFit() 将标签折叠到其内容大小

【讨论】:

.fill 是解决方案

以上是关于UITableViewCell 中带有多行标签的 UIStackView 高度不正确的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 中带有 UIImages 的 UIButton - 重叠等

在 xib 中带有可选 UIImageView 的自定义 UITableViewCell

UITableViewCell 内的多个堆栈视图内的多行标签

自定义 UITableviewCell 中的多行标签

UITableViewCell 中的几个多行标签,情节提要 xcode 6.3.2 中的自动布局

iOS 9 上的静态 UITableViewCell 中的多行 UILabel