首页 > 解决方案 > UITableview 部分 - 如何正确重新计算高度?

问题描述

视频:

https://youtu.be/sSHrxSIHUM4

正如您在视频中看到的那样,我遇到了问题。图像高度约束被破坏,导致标签也缺少高度。它们位于 tableview (class UITableHeaderFooter) 部分。我曾经automaticDimension计算过它的高度,结果得到了纠正。

这是图像视图约束。(默认高度约束为 184 并且在运行时更新取决于比率。)

https://uphinhnhanh.com/image/SAezyz

和标签约束:

https://uphinhnhanh.com/image/SAeT5Y

问题发生在我打电话table reload重新配置剖面视图数据和高度然后下载图像之后。我收到了损坏的约束警告。Xcode 打破了导致问题的 imageview 高度约束。

(
    "<NSLayoutConstraint:0x2807252c0 UIImageView:0x109c002d0.height == 735.885   (active)>",
    "<NSLayoutConstraint:0x280727160 UIImageView:0x109c007f0.height == 40   (active)>",
    "<NSLayoutConstraint:0x280715900 UIView:0x109c00d10.height == 51   (active)>",
    "<NSLayoutConstraint:0x2807140f0 UILayoutGuide:0x281d7e680'UIViewSafeAreaLayoutGuide'.bottom == UIView:0x109c00d10.bottom   (active)>",
    "<NSLayoutConstraint:0x2807174d0 V:|-(11)-[UIImageView:0x109c007f0]   (active, names: '|':engie_up.PostDetailHeaderView:0x109c00000 )>",
    "<NSLayoutConstraint:0x280717c50 V:[UIImageView:0x109c007f0]-(18.5)-[engie_up.KwExpandableContextLabel:0x10491c600'bfbfnff']   (active)>",
    "<NSLayoutConstraint:0x280715130 V:[engie_up.KwExpandableContextLabel:0x10491c600'bfbfnff']-(18)-[UIImageView:0x109c002d0]   (active)>",
    "<NSLayoutConstraint:0x280714fa0 V:[UIImageView:0x109c002d0]-(0)-[UIView:0x109c00d10]   (active)>",
    "<NSLayoutConstraint:0x28072ad00 'UIView-Encapsulated-Layout-Height' engie_up.PostDetailHeaderView:0x109c00000.height == 343   (active)>",
    "<NSLayoutConstraint:0x2807179d0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x281d7e680'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':engie_up.PostDetailHeaderView:0x109c00000 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x2807252c0 UIImageView:0x109c002d0.height == 735.885   (active)>

我注意到这'UIView-Encapsulated-Layout-Height'是估计高度。

获取代码很简单,因为我使用的是 Kingfisher

let ratio = CGFloat(image.width) / CGFloat(image.height)
userContentImageViewHeightConstraint.constant = CGFloat((UIScreen.main.bounds.width) / ratio)
self.userContentImageView.kf.indicatorType = .activity
self.userContentImageView.kf.setImage(with: URL(string: image.url), completionHandler: { (_, _, _, _) in
     self.setNeedsLayout()
     self.layoutIfNeeded()
     })

所以我想问一下如何正确修复约束中断?

谢谢你。

标签: iosuitableviewautolayoutkingfisher

解决方案


更新:我删除了图像高度约束并添加了纵横比约束,现在中断消失了,但在视频中得到了相同的结果

        let ratio = CGFloat(image.width) / CGFloat(image.height)
        let constraint = NSLayoutConstraint(item: self.userContentImageView,
                                            attribute: NSLayoutConstraint.Attribute.width,
                                            relatedBy: NSLayoutConstraint.Relation.equal,
                                            toItem: self.userContentImageView,
                                            attribute: NSLayoutConstraint.Attribute.height,
                                            multiplier: ratio,
                                            constant: 0.0)
        constraint.priority = 999
        self.userContentImageViewAspectConstraint = constraint

更新 2:2019 年 1 月 18 日

最后,我找到了问题的根本原因。我没有注意到底部视图的底部约束与安全区域布局对齐。这导致在开始时,视图被拉到标签栏上方,并产生了额外的空间并破坏了图像约束的高度(其优先级为 999)。我将其更改为与超级视图对齐,然后问题消失了。


推荐阅读