如何将固定高度视图添加到垂直堆栈视图?

Posted

技术标签:

【中文标题】如何将固定高度视图添加到垂直堆栈视图?【英文标题】:How do I add fixed height views to vertical stack view? 【发布时间】:2019-06-20 12:20:30 【问题描述】:

我有一个垂直的 UIStackView,我正在尝试将多个视图添加到堆栈视图中,所有视图的固定高度均为 50。

我已在我的 xib 中将堆栈视图上的对齐和分布设置为 Fill。

let button = UIButton()
                    button.setTitle(card.title, for: .normal)
                    button.layer.cornerRadius = 10
                    button.layer.backgroundColor = UIColor.red.cgColor

                    let damageCardConstraint = button.heightAnchor.constraint(equalToConstant: 50)
                    damageCardConstraint.isActive = true

//                        let label = UILabel()
//                        label.text = $0.title
                    self?.damageCardView.addArrangedSubview(button)

我希望视图以固定高度 50 添加到堆栈视图中。相反,我得到一个高度填充堆栈视图高度的视图(高度为 200)。我也在控制台中得到了这个

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600002288140 UIStackView:0x7f894df03c50.height == 400   (active)>",
    "<NSLayoutConstraint:0x60000228b0c0 UIButton:0x7f894dd0ed90'Wounded Pilot'.height == 50   (active)>",
    "<NSLayoutConstraint:0x60000228b070 'UISV-canvas-connection' UIStackView:0x7f894df03c50.top == UIButton:0x7f894dd0ed90'Wounded Pilot'.top   (active)>",
    "<NSLayoutConstraint:0x60000228b570 'UISV-canvas-connection' V:[UIButton:0x7f894dd0ed90'Wounded Pilot']-(0)-|   (active, names: '|':UIStackView:0x7f894df03c50 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60000228b0c0 UIButton:0x7f894dd0ed90'Wounded Pilot'.height == 50   (active)>

所以看起来我添加的约束被打破了。我不确定应该删除哪个约束来解决我的问题。

【问题讨论】:

请发布问题的完整背景 显示堆栈视图配置。 【参考方案1】:

你可以试试这个,它对我有用。 你必须接受堆栈视图高度约束

var numberOfButtonsYouWant = 10

@IBOutlet weak var stackViewHeightConstraint: NSLayoutConstraint!

如果您不想重复按钮,则可以在添加新按钮之前删除堆栈视图的所有排列子视图

stackViewHeightConstraint.constant = CGFloat(numberOfButtonsYouWant) * button.frame.size.height
damageCardConstraint.translatesAutoresizingMaskIntoConstraints = false
damageCardConstraint.addArrangedSubview(button)

【讨论】:

【参考方案2】:

你需要在底部有一个填充视图,否则stackView会拉伸最后一个视图来填充剩余空间,看这个例子:

import UIKit
import PlaygroundSupport

class VC: UIViewController 

    override func loadView() 
        let views = [UIColor.red, .blue, .green]
            .map(viewWith)
        views.forEach 
            $0.heightAnchor.constraint(equalToConstant: 50).isActive = true
        
        let filler = UIView()
        filler.backgroundColor = .white
        let stackView = UIStackView(arrangedSubviews: views + [filler])
        stackView.axis = .vertical
        stackView.distribution = .fill
        stackView.alignment = .fill
        view = stackView
    

    func viewWith(color: UIColor) -> UIView 
        let view = UIView()
        view.backgroundColor = color
        return view
    


PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = VC()

【讨论】:

以上是关于如何将固定高度视图添加到垂直堆栈视图?的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 具有嵌入式垂直堆栈视图设置,具有自动布局和动态高度

在垂直堆栈视图中设置图像子视图的高度

图像视图autolayout从水平边缘固定到60pt,但自动刻度高度?

在水平堆栈视图(自动布局)中将文本与图像垂直居中 - iOS

相对于堆栈视图高度约束 UIStackView 的子视图

基于子视图的 UIStackView 容器视图高度