简体   繁体   中英

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?

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
})

安排的子视图动画Gif

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
}

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

动画

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()
}

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
        }

    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM