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

Posted

技术标签:

【中文标题】在垂直堆栈视图中设置图像子视图的高度【英文标题】:Set height of image subview in vertical stack view 【发布时间】:2019-06-18 15:51:27 【问题描述】:

我有一个UITableViewCell,其中包含堆叠模式的内容。

    标题 (UILabel) 子标题 (UILabel) 图片 (UIImageView) 内容正文 (UILabel)

图像不是固定高度,我是从远程资源下载的,但是,我在渲染 cell 之前知道高度,因为它包含在初始 API 响应中。

我正在尝试根据我在模型上持有的值设置此图像的高度,但是,我一直遇到autolayout 问题:

(
    "<NSLayoutConstraint:0x283c90d20 V:|-(8)-[UIStackView:0x1050072a0]   (active, names: '|':UITableViewCellContentView:0x105007ad0 )>",
    "<NSLayoutConstraint:0x283c90e10 UIStackView:0x1050072a0.bottom == UITableViewCellContentView:0x105007ad0.bottom - 8   (active)>",
    "<NSLayoutConstraint:0x283c90eb0 UIImageView:0x1050074a0.height == 220.073   (active)>",
    "<NSLayoutConstraint:0x283cb9720 'UISV-canvas-connection' UIStackView:0x1050072a0.top == UILabel:0x1050034a0'Hey you, get off my cloud'.top   (active)>",
    "<NSLayoutConstraint:0x283cb8910 'UISV-canvas-connection' V:[UIImageView:0x1050074a0]-(0)-|   (active, names: '|':UIStackView:0x1050072a0 )>",
    "<NSLayoutConstraint:0x283cb8190 'UISV-spacing' V:[UILabel:0x1050034a0'Hey you, get off my cloud']-(0)-[UILabel:0x105003790'You don't know me and you...']   (active)>",
    "<NSLayoutConstraint:0x283cb81e0 'UISV-spacing' V:[UILabel:0x105003790'You don't know me and you...']-(0)-[UIImageView:0x1050074a0]   (active)>",
    "<NSLayoutConstraint:0x283cba850 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x105007ad0.height == 16   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x283c90eb0 UIImageView:0x1050074a0.height == 220.073   (active)>

我正在以编程方式布置我的视图,如下所示:

class ArticleBodyCell: UITableViewCell 

    private var articleImageViewHeight: NSLayoutConstraint!

    private let contentStackView = UIStackView(frame: .zero)
    private lazy var articleHeader = UILabel(
        font: theme.font(.header),
        textColor: theme.color(.text),
        numberOfLines: 0
    )
    private lazy var articleSummary = UILabel(
        font: theme.font(.headerSmall),
        textColor: theme.color(.text),
        numberOfLines: 0
    )

    private let articleImageView = UIImageView(frame: .zero)

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

    required init?(coder aDecoder: NSCoder) 
        return nil
    

    func render(model: ContentArticle?) 
        guard let model = model else  return 

        articleHeader.text = model.title
        articleSummary.text = model.description

        if let asset = model.assets.first, let storageUri = asset?.storageUri 
            articleImageViewHeight.constant = model.heightForArticle

            print("do something w/",storageUri)

        
    

    func anchorSubViews() 

        contentView.addSubview(contentStackView)

        contentStackView.translatesAutoresizingMaskIntoConstraints = false

        articleImageViewHeight = articleImageView.heightAnchor.constraint(equalToConstant: 0)
        articleImageViewHeight.isActive = true

        NSLayoutConstraint.activate([
            contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
            contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8),
            contentStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
            contentStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8)
        ])

        contentStackView.axis = .vertical
        contentStackView.distribution = .fill

        [articleHeader, articleSummary, articleImageView].forEach  contentStackView.addArrangedSubview($0) 
    

我想也许通过捕获articleImageViewHeight 我可以在单元格渲染上处理模型时设置高度,但这似乎不起作用。

编辑 我还尝试使用以下方法调整锚点的priority,但这没有效果。

contentStackViewBottomAnchor = contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor)
contentStackViewBottomAnchor.priority = .init(999)
contentStackViewBottomAnchor.isActive = true

【问题讨论】:

【参考方案1】:

在您的articleImageViewHeight 上设置优先级。

我认为将其设置在 contentView 上不会产生任何影响。

articleImageViewHeight = articleImageView.heightAnchor.constraint(equalToConstant: 0)
articleImageViewHeight.priority = .init(999)
articleImageViewHeight.isActive = true

【讨论】:

以上是关于在垂直堆栈视图中设置图像子视图的高度的主要内容,如果未能解决你的问题,请参考以下文章

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

相对于堆栈视图高度,限制UIStackView的子视图

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

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

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

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