I'm a little late to the Auto Layout party, but I've been trying for a couple of days to understand why some of my animated constraint changes don't always work, nor do they produce any errors in the console.
Essentially, I have:
- Two containers (top: red, bottom: orange)
- A child view label (yellow - the one which says "Hello!") in the bottom view (orange)
As you can see from the GIF, adjusting the height of the top (red) view causes the orange container to grow... which in turn also causes the yellow view to stretch with it. However, when the red view becomes smaller, I get some weird behaviour with the yellow view immediately shrinking down to size, rather than following the animation of the orange view.
My constraints are configured as follows:
topViewHeightConstraint = topView.heightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.7)
NSLayoutConstraint.activate([
// Setup the top view
topView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
topView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
topView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
topViewHeightConstraint!,
// Setup the constraits for the button inside the top view
topViewButton.centerXAnchor.constraint(equalTo: topView.centerXAnchor),
topViewButton.bottomAnchor.constraint(equalTo: topView.bottomAnchor, constant: -20),
topViewButton.widthAnchor.constraint(equalToConstant: 100),
topViewButton.heightAnchor.constraint(equalTo: topViewButton.widthAnchor, multiplier: 1.0),
// Setup the bottom view
bottomView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
bottomView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
bottomView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
bottomView.topAnchor.constraint(equalTo: topView.bottomAnchor),
// Setup constraints for the label
labelInsideBottomView.bottomAnchor.constraint(equalTo: self.bottomView.bottomAnchor),
labelInsideBottomView.leadingAnchor.constraint(equalTo: self.bottomView.leadingAnchor),
labelInsideBottomView.trailingAnchor.constraint(equalTo: self.bottomView.trailingAnchor),
labelInsideBottomView.widthAnchor.constraint(equalTo: self.bottomView.widthAnchor),
labelInsideBottomView.heightAnchor.constraint(equalTo: self.bottomView.heightAnchor)
])
Then, to resize the container view I'm calling the following code (with help of an extension to replace a multiplier constraint), I'm updating the constraint.
func moveViews() {
if (topViewHeightConstraint.multiplier >= 0.69) {
topViewHeightConstraint = topViewHeightConstraint.setMultiplier(multiplier: 0.5)
} else {
topViewHeightConstraint = topViewHeightConstraint.setMultiplier(multiplier: 0.7)
}
UIView.animate(withDuration: 1) {
self.view.layoutIfNeeded()
}
}
Can anyone see anything unusual about my setup, or suggest a way I can achieve this without the weird animation?
Thanks!