Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIStackView Hiding/UnHiding arrangedSubView issue

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

enter image description here

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

like image 273
Meet Avatar asked Oct 20 '25 13:10

Meet


2 Answers

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
    }
}
like image 111
Vadim Zhuk Avatar answered Oct 23 '25 02:10

Vadim Zhuk


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 }
like image 34
Sergii Kostanian Avatar answered Oct 23 '25 03:10

Sergii Kostanian