I've got two UILabels embedded within a UIStackView. The top label stays visible constantly, but the bottom label is toggled on and off via the hidden
property. I wanted this effect to be animated, so I stuck it in an animation block:
private func toggleResultLabel(value:Double) {
if value == 0 {
UIView.animateWithDuration(0.25) { () -> Void in
self.resultLabel.hidden = true
}
} else {
UIView.animateWithDuration(0.25) { () -> Void in
// Something weird is happening. I had to add 3 of the same statements to get
// the hidden flag to be false
self.resultLabel.hidden = false
self.resultLabel.hidden = false
self.resultLabel.hidden = false
}
}
}
The problem is that the hidden property will not change unless I repeat the statement over and over (3 times in this case). I found this while breaking into the animation closure and seeing that the property would not change to it's assignment. Now I'm noticing the same problem occurring seemingly randomly again. The default value of the second label is true
, if that's relevant.
Is there something I'm missing here, or is this a bug?
Update:
For what it's worth, I got it working by adding removeArrangedSubview()
and addArrangedSubview()
:
if value == 0 {
UIView.animateWithDuration(0.25) { () -> Void in
self.resultLabel.hidden = true
self.heroStackView.removeArrangedSubview(self.resultLabel)
}
} else {
UIView.animateWithDuration(0.25) { () -> Void in
self.heroStackView.addArrangedSubview(self.resultLabel)
self.resultLabel.hidden = false
}
}
On iOS 11 and prior, when hiding an arrangedSubview
of a UIStackView
using UIView animation API multiple times, the hidden property values "stack", and it requires setting hidden to false
multiple times before the value actually changes.
At work we decided to use a UIView extension with a workaround method that sets hidden only once for given value.
extension UIView {
// Workaround for the UIStackView bug where setting hidden to true with animation
// mulptiple times requires setting hidden to false multiple times to show the view.
public func workaround_nonRepeatingSetHidden(hidden: Bool) {
if self.hidden != hidden {
self.hidden = hidden
}
}
}
This is definitely a bug in UIKit, check out the sample project that reproduces it clearly.
In considering UIStackView bug I decide to check hidden property.
if myView.hidden != hidden {
myView.hidden = hidden
}
It's not the most elegant solution but it works for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With