Forgive me if explanation is not excellent. Basically, the video below shows the standard animation for hiding labels in a stack view. Notice it looks like the labels "slide" and "collapse together".
I still want to hide the labels, but want an animation where the alpha changes but the labels don't "slide". Instead, the labels change alpha and stay in place. Is this possible with stack views?
This is the code I have to animate:
UIView.animate(withDuration: 0.5) {
if self.isExpanded {
self.topLabel.alpha = 1.0
self.bottomLabel.alpha = 1.0
self.topLabel.isHidden = false
self.bottomLabel.isHidden = false
} else {
self.topLabel.alpha = 0.0
self.bottomLabel.alpha = 0.0
self.topLabel.isHidden = true
self.bottomLabel.isHidden = true
}
}
Update 1
It seems that even without a stack view, if I animate the height constraint, you get this "squeeze" effect. Example:
UIView.animate(withDuration: 3.0) {
self.heightConstraint.constant = 20
self.view.layoutIfNeeded()
}

Here are a couple options:
Set
.contentMode = .topon the labels. I've never found Apple docs that clearly describe using.contentModewithUILabel, but it works and should work.Embed the label in a
UIView, constrained to the top, withContent Compression Resistance Priorityset to.required, less-than-required priority for the bottom constraint, and.clipsToBounds = trueon the view.Example 1 - content mode:
Example 2 - label embedded in a
UIView:Edit
If your goal is to have the Brown label "slide up and cover" both the Blue and Pink labels, with neither of those labels compressing or moving, take a similar approach:
The arranged subviews of the "outer" stack view will now be:
and to animate we'll toggle the
.alphaand.isHiddenon the "container" view instead of the Blue and Pink labels.I edited the controller class -- give it a try and see if that's the effect you're after.
If it is, I strongly suggest you try to make those changes yourself... if you run into problems, use this example code as a guide:
Edit 2
A quick explanation of why this works...
Consider a typical
UILabelas a subview of aUIView. We constrain the label to the view on all 4 sides with a little "padding":Now we can constrain the view's Top / Leading / Trailing -- but not Bottom or Height -- and the label's intrinsic Height will control the Height of the view.
Pretty basic.
But, if we want to "animate it out of existence," changing the Height of the view will also change the Height of the label, resulting in a "squeeze" effect. We'll also get auto-layout complaints, because the constraints cannot be satisfied.
So, we need to change the
.priorityof the label's Bottom constraint to allow it to remain at its intrinsic Height, while its superview's Height changes.Each of these 4 examples uses the same Top / Leading / Trailing constraints... the only difference is what we do with the Bottom constraint:
For Example 1, we don't set any Bottom constraint. So, we never even see its superview and animating the Height of its superview has no effect on the label.
For Example 2, we set the "normal" Bottom constraint, and we see the "squeezing" effect.
For Example 3, we give the label's Bottom constraint
.priority = .defaultHigh. The label still controls the Height of its superview... until we activate the superview's Height constraint (of zero). The superview collapses, but we've given auto-layout permission to break the Bottom constraint.Example 4 is the same as 3, but we've also set
.clipsToBounds = trueon the container view so the label Height remains constant, but no longer extends outside its superview.All of that also applies to views in a stack view when setting
.isHiddenon an arranged subview.Here's the code that generates that example, if you want to inspect it and play around with the variations: