I am hiding and unhiding dropDownView(UIView consisting of textfield and button) based on Segment tapped in Segment Control. Following is the view hierarchy :-

Following is the code which hides/unhides dropDownView :-
private func animateView(view: UIStackView, toHidden hidden: Bool) {
UIView.animate(withDuration: 0.25)
{
let firstView = view.arrangedSubviews[0]
firstView.isHidden = hidden
}
}
func segmentValueChanged(_ sender: UISegmentedControl) {
let segmentSelected = segmentControl.selectedSegmentIndex
switch segmentSelected {
case 0:
animateView(view: mainStackView, toHidden: true)
case 1:
animateView(view: mainStackView, toHidden: true)
case 2:
animateView(view: mainStackView, toHidden: true)
case 3:
animateView(view: mainStackView, toHidden: false)
default:
break
}
}
Problem which I am facing is after changing segments over 10-15 times the above code stops working and DropDown View overlaps with Segment Control and I am not sure why. Any help to understand this issue is appreciated.
Also I have already tried
1. setNeedsLayout,
2. setNeedsDisplay and
3. reducing priority to height constraint of dropDownView to 999 from
1000
Seem the additional setting isHidden in completionClosure fixes that issue (Swift 5 syntax):
private func animateView(view: UIStackView, toHidden hidden: Bool) {
let firstView = view.arrangedSubviews[0]
UIView.animate(withDuration: 0.25) {
firstView.isHidden = hidden
view.layoutIfNeeded()
} completion {
firstView.isHidden = hidden
}
}
I've noticed that sometimes when you hide an arrangedSubview it doesn't hide its subviews, so here is the solution (or rather workaround) that works for me (firstView and secondView here are arrangedSubviews of some UIStackView):
firstView.isHidden = false
firstView.subviews.forEach { $0.isHidden = false }
secondView.isHidden = true
secondView.subviews.forEach { $0.isHidden = true }
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