简体   繁体   English

UIStackView 内 UIView 的动态高度

[英]Dynamic height of a UIView inside a UIStackView

Note: Similar questions have been asked on this topic but for some reason, the solutions mentioned in them doesn't seem to work for me so I'm posting this.注意:关于这个主题已经提出了类似的问题,但由于某种原因,其中提到的解决方案似乎对我不起作用,所以我发布了这个。


I have a UIScrollView that fills the entire view of a view controller and a vertical UIStackView embedded inside it.我有一个UIScrollView填充视图 controller 的整个视图和嵌入其中的垂直UIStackView

class ViewController: UIViewController {
    private let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.showsVerticalScrollIndicator = false
        return scrollView
    }()
    lazy private var cardsStackView: UIStackView = {
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.spacing = 8
        stackView.distribution = .fill
        return stackView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .secondarySystemBackground
        
        view.addSubview(scrollView)
        scrollView.addSubview(cardsStackView)
        let padding: CGFloat = 10
        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: padding),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -padding),
            
            cardsStackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            cardsStackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            cardsStackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            cardsStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            cardsStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
        ])
        
        addCardViews()
    }
}

I want to add a number of UIView subclasses ( CardView ) to this stack view.我想在这个堆栈视图中添加一些UIView子类( CardView )。 These CardView s only contain two UILabels and this view is made to resize to fit the content of these labels.这些CardView只包含两个UILabels并且这个视图被调整大小以适应这些标签的内容。

class CardView: UIView {
    lazy private var titleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 15, weight: .semibold)
        return label
    }()
    lazy private var detailLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
        label.numberOfLines = 0
        return label
    }()
    
    init(title: String, details: String) {
        super.init(frame: .zero)
        titleLabel.text = title
        detailLabel.text = details
        commonInit()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        backgroundColor = .systemGreen
        
        layoutViews()
    }
    
    private func layoutViews() {
        translatesAutoresizingMaskIntoConstraints = false
        
        addSubview(titleLabel)
        addSubview(detailLabel)
        NSLayoutConstraint.activate([
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            titleLabel.topAnchor.constraint(equalTo: topAnchor),
            titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
            
            detailLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            detailLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6),
            detailLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
        ])
    }
}

When I add these card views to the stack view, they don't seem to lay out one after the other.当我将这些卡片视图添加到堆栈视图时,它们似乎并没有一个接一个地布置。

在此处输入图像描述

It seems like the view is not taking the intrinsic content size of the labels when calculating the height of the view.在计算视图的高度时,视图似乎没有采用标签的固有内容大小。

Any idea how to resolve this?知道如何解决这个问题吗?

In your CardView you miss the detailLabel bottom anchor:在您的CardView ,您错过了detailLabel底部锚点:

private func layoutViews() {
    translatesAutoresizingMaskIntoConstraints = false
    
    addSubview(titleLabel)
    addSubview(detailLabel)
    NSLayoutConstraint.activate([
        titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
        titleLabel.topAnchor.constraint(equalTo: topAnchor),
        titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
        
        detailLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
        detailLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6),
        detailLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
        // This is missing 
        detailLabel.bottomAnchor.constraint(equalTo: bottomAnchor) 
    ])
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM