具有Autolayout和UITableAutomaticDimension的动态高度表单元格(动态UILabel +几个UIImageViews)

时间:2017-02-14 09:30:32

标签: ios objective-c iphone uitableview autolayout

我查看了与动态表格单元格和自动布局相关的文章3天,到目前为止还没有工作。

下面是我想要的表格单元格。这里的主要问题是UILabel用于发布文本和UIImages。

enter image description here

这是UI元素的层次结构。

- Content View
    + ...
    + UILabel for text - dynamic height
    + UIView - image view container
        * UIImageView
        * UIImageView
        * ....

Label具有换行符模式换行文本和行设置为0。 标签和容器视图具有顶部,底部,前导和尾随的约束。 ImageViews在运行时添加,并具有顶部,前导,尾随,底部和高度约束的约束。 第一个图像视图对容器视图有最高约束,最后一个图像视图对容器视图有底部约束,而其他图像视图对上部图像视图有最高约束。

enter image description here

当第一次加载表格时(单元格具有不同的图像计数),它看起来很好,但是当我向上和向下滚动时,某些单元格中的约束会中断,并且图像在单元格内部会重叠。

以下是错误输出:

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:0x17428aaf0 V:|-(0)-[UIImageView:0x14be77ed0]   (active, names: '|':UIView:0x14be75b20 )>",
"<NSLayoutConstraint:0x17428a6e0 UIImageView:0x14be77ed0.height == 160   (active)>",
"<NSLayoutConstraint:0x17428acd0 UIImageView:0x14be77ed0.bottom == UIView:0x14be75b20.bottom   (active)>",
"<NSLayoutConstraint:0x174289650 V:|-(0)-[UIImageView:0x14be43ce0]   (active, names: '|':UIView:0x14be75b20 )>",
"<NSLayoutConstraint:0x17428bb80 UIImageView:0x14be43ce0.height == 160   (active)>",
"<NSLayoutConstraint:0x17428be50 V:[UIImageView:0x14be43ce0]-(10)-[UIImageView:0x14be74b10]   (active)>",

"<NSLayoutConstraint:0x17428bfe0 UIImageView:0x14be74b10.height == 160   (active)>",
"<NSLayoutConstraint:0x17428c080 UIImageView:0x14be74b10.bottom == UIView:0x14be75b20.bottom   (active)>"

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x17428be50 V:[UIImageView:0x14be43ce0]-(10)-[UIImageView:0x14be74b10]   (active)>

请帮我解决这个问题。谢谢。

3 个答案:

答案 0 :(得分:1)

要确保在单元格出列时堆栈视图不包含旧图像,您需要在prepareForReuse()中清除它:

override func prepareForReuse() {
    super.prepareForReuse()

    stack.arrangedSubviews.forEach {
        stack.removeArrangedSubview($0)
        $0.removeFromSuperview()
    }
}

答案 1 :(得分:0)

我建议不要给你的图像高度,而是在容器视图中添加垂直stackview并在其中添加所有图像。确保他们将内容模式设置为宽高比适合,stackview应该处理其余部分。不要忘记将stackview限制在标签的底部和单元格的底部,因此它知道它有多少空间。它将自己处理你的图像

答案 2 :(得分:0)

  

ImageViews在运行时添加,并对顶部,前导,尾随,底部和高度约束有约束。

这是您的错误消息。移除 高度或您选择底部或顶部约束的约束之一。您不能限制所有4个边并为其添加高度常量。

<强>旁注:

对于宽度也是如此,如果设置了宽度约束,则不能同时限制两边的前导/尾随。

修改

此外,根据评论部分的建议,使用UIStackView可以更轻松。