Seishin
Seishin

Reputation: 1477

View is not redrawing after width constraint update

I have the following case: UIImageView that its width needs to be incremented on specific event. When I try to increment it, the constraint is incrementing but the view isn't redrawing.

The UIImageView has bottom, top and left constraints and one width initially set to 0.

Here is an image from the Debug View Hierarchy: enter image description here

The updating width code:

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

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

Upvotes: 1

Views: 2726

Answers (2)

emrepun
emrepun

Reputation: 2666

If you are facing the same problem in a view that subclasses UIView and this view has custom sublayers, you could make sure all sublayers are updated when the view's frame changed (due to some constraints update or any other reason) by overriding layoutSublayers(of:CALayer) function in view's class as following:

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()
        }
    }
}

We also make sure that layer updates are immediately applied without any animation or delay by making use of CATransaction

Upvotes: 0

Seishin
Seishin

Reputation: 1477

I solved it by myself. The problem is that the constraint and respectively the frame of the view are correctly updated but the view's layer was not... The solution was to force the layer to redraw itself with .setNeedsDisplay()

I spent more than 4 hours in searching for a solution to this stupid issue...

Upvotes: 2

Related Questions