Andrey Gordeev
Andrey Gordeev

Reputation: 32549

UIStackView - hide and collapse subview with animation

I'm trying to hide UIStackView's subview like this:

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 2.0, 
      delay: 0, options: [.curveEaseOut], animations: {
    self.label.isHidden = true
    self.label.alpha = 0.0
    self.stackView.layoutIfNeeded()
})

However, the label disappears instantly with using this code. I suspect this is because of setting isHidden to true, which is required for collapsing.

Is there a way how to hide and collapse UIStackView's subvew with animation? Or it might be better to not to use UIStackView at all?

Upvotes: 20

Views: 24823

Answers (5)

Wez
Wez

Reputation: 10712

According to Apple's documentation:

You can animate both changes to the arranged subview’s isHidden property and changes to the stack view’s properties by placing these changes inside an animation block.

I've tested the below code using iOS 12.1 Simulator and it works as expected.

UIView.animate(
    withDuration: 2.0,
    delay: 0.0,
    options: [.curveEaseOut],
    animations: {
        self.label.isHidden = true
        self.label.alpha = 0.0
})

Arranged Subview Animation Gif

Upvotes: 35

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

Just you can use simple solution with animateKeyframes to fade alpha , then hide , i think this will give you what you need So hide after 1 Sec and 0.8 Sec fading

// showLabel is Bool to handle status declare it at you File

@IBAction func toggleStackLabelTapped(_ sender: UIButton) {

    showLabel = !showLabel

    UIView.animateKeyframes(withDuration: 1, delay: 0, options: .calculationModeLinear, animations: {
        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.8) {
            self.label.alpha =  (self.showLabel) ? 1 : 0
        }
        UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 1) {
            self.label.isHidden = !self.showLabel
        }

    })
}

Upvotes: 1

Kathiresan Murugan
Kathiresan Murugan

Reputation: 2962

I have tried your code. Its animating

if self.stackView.subviews.count > 0 {
            UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 1.0, delay: 0, options: [.curveEaseOut], animations: {

                self.stackView.subviews[0].isHidden = true
                self.stackView.subviews[0].alpha = 0.0
                self.stackView.layoutIfNeeded()
            }) { (position) in
                self.stackView.subviews[0].removeFromSuperview()
            }
        }

initialScreen

animated

Upvotes: 3

Sand'sHell811
Sand'sHell811

Reputation: 388

make sure you have not given height constraint to the stackview. and try this.

UIView.animate(withDuration: 0.5) {
   self.stackView.subviews[INDEX_OF_LABEL_IN_STACK]?.alpha = 0
   self.stackView.subviews[INDEX_OF_LABEL_IN_STACK]?.isHidden = true
   self.view.layoutSubviews()
}

Upvotes: -2

ZGski
ZGski

Reputation: 2548

You can animate view properties like alpha, color, etc. However, some things happen instantly - isHidden in this case.

Here's an example using UIView.animate:

UIView.animate(withDuration: 2, delay: 0, options: .curveEaseOut, animations: {
    self.label.alpha = 0 // Changes the label's layer alpha value
}, completion: { finished in
    self.label.isHidden = true // Hides the label
    self.label.layer.alpha = 1 // Resets the label's alpha without un-hiding it
})

Using UIViewPropertyAnimator:

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 2, delay: 0, options: .curveEaseOut, animations: {
    self.label.alpha = 0 // Sets the label's alpha
}) { _ in
    self.label.isHidden = true // Hides the label
    self.label.alpha = 1 // Resets the label's alpha without un-hiding it
}

Upvotes: 4

Related Questions