1

I'm using UIStackView and it contains 3 UIView instances, which has fixed height

I'm trying to hide these subviews by clicking button

first and second view show/hide well with proper animation

but last view doesn't animate

enter image description here

enter image description here

class ViewController: UIViewController {
    private var flag: Bool = true
    @IBOutlet weak var targetView: UIView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    @IBAction func buttonDidTapped(_ sender: Any) {
        flag = !flag
        
        UIView.animate(withDuration: 0.5) {
            self.view.layoutIfNeeded()
            self.targetView.isHidden = !self.flag
        }
        
    }
}


PrepareFor
  • 2,448
  • 6
  • 22
  • 36

2 Answers2

1

The issue is the way stack views change their frames when hiding an arranged subview.

Easiest way to see what's happening:

  • set your Green view to Alpha: 0.5
  • toggle .isHidden on the Blue view

You'll see that the 50% translucent Green view "slides up over" the Blue view... the Blue view does not "shrink in height" during the animation.

To solve your specific issue, set Clips To Bounds to true on your stack view. Now, when you toggle .isHidden on your Green view, the animation will look correct.

That will not change the "slide over" appearance if you have translucent views, but that's a different issue.

As a side note, you can simplify your code and get rid of the flag like this:

    UIView.animate(withDuration: 0.5) {
        // not needed
        //self.view.layoutIfNeeded()
        self.targetView.isHidden.toggle()
    }
DonMag
  • 69,424
  • 5
  • 50
  • 86
0

Try change your code from:

    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
        self.targetView.isHidden = !self.flag
    }

to:

    self.targetView.isHidden = !self.flag

    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }

Looks like you animate before change.

Hopsa
  • 425
  • 3
  • 10