宽度约束更新后视图未重绘

Posted

技术标签:

【中文标题】宽度约束更新后视图未重绘【英文标题】:View is not redrawing after width constraint update 【发布时间】:2016-12-20 08:55:35 【问题描述】:

我有以下情况: UIImageView 它的宽度需要在特定事件上增加。当我尝试增加它时,约束在增加,但视图没有重绘。

UIImageView 具有底部、顶部和左侧约束,并且一个宽度最初设置为 0。

这是来自调试视图层次结构的图像:

更新宽度代码:

self.view.layoutIfNeeded()
self.progressBarThumbWidthConstraint.constant += 30
self.view.updateConstraintsIfNeeded()

UIView.animate(withDuration: 0.3, animations: 
    self.view.layoutIfNeeded()
)

【问题讨论】:

【参考方案1】:

我自己解决了。 问题是视图的约束和相应的框架都已正确更新,但视图的图层没有......解决方案是强制图层使用.setNeedsDisplay()重绘自身@

我花了 4 个多小时来寻找这个愚蠢问题的解决方案......

【讨论】:

【参考方案2】:

如果您在子类UIView 的视图中遇到同样的问题并且该视图具有自定义子层,您可以确保在视图的框架发生更改时(由于某些约束更新或任何其他原因)更新所有子层覆盖视图类中的layoutSublayers(of:CALayer) 函数如下:

override func layoutSublayers(of layer: CALayer) 
    if layer == self.layer 
        layer.sublayers?.forEach 
            // By disabling actions we make sure that
            // frame changes for sublayers are applied immediately without animation
            CATransaction.begin()
            CATransaction.setDisableActions(true)
            $0.frame = layer.bounds
            CATransaction.commit()
        
    

我们还通过使用CATransaction 确保立即应用层更新而没有任何动画或延迟

【讨论】:

以上是关于宽度约束更新后视图未重绘的主要内容,如果未能解决你的问题,请参考以下文章

vue基本知识点

如何让 UIStackView 更新其布局?

更新数据异步后重绘 UITableView

如何仅刷新/重绘 uicollectionview 中的补充视图?

如何在不重绘整个视图的情况下更新 NSView 的一部分

ObservedObject 未触发视图重绘