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
Try without your animate function as stackView should animate hiding and unhiding anyway. Add a check for hidden status and only change it if necessary:
func segmentValueChanged(_ sender: UISegmentedControl) {
let segmentSelected = segmentControl.selectedSegmentIndex
let dropDown = mainStackView.arrangedSubviews.first!
switch segmentSelected {
case 0, 1, 2:
if !dropDown.isHidden {
dropDown.isHidden = true
}
case 3:
if dropDown.isHidden {
dropDown.isHidden = false
}
default:
break
}
}
Try this one below. Hope will solve your problem.
private func animateView(view: UIStackView, toHidden hidden: Bool) {
let firstView = view.arrangedSubviews[0]
UIView.animate(withDuration: 0.25) {
firstView.isHidden = hidden
view.layoutIfNeeded()
}
}
Following is the solution that I implemented which seems to work:-
private func animateView(view: UIStackView, toHidden hidden: Bool) {
if !hidden
{
mainStackView.insertArrangedSubview(view, at: 0)
view.isHidden = true
UIView.animate(withDuration: 0.25, animations: {
view.isHidden = false
})
} else {
let firstView = mainStackView.arrangedSubviews[0]
UIView.animate(withDuration: 0.25, animations: {
if firstView == view {
firstView.isHidden = true
}
}, completion: { [weak self] _ in
if firstView == view {
self?.mainStackView.removeArrangedSubview(firstView)
firstView.removeFromSuperview()
}
})
}
}
Creating DropDown View programmatically (Instead of creating in storyboard) and removing same on every completion. I am not marking this answer correct as its a workaround. I want to understand why storyboard dropDownView fails after 10-15 tries.