ios UIStackView 隐藏视图动画

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46326302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:30:09  来源:igfitidea点击:

UIStackView Hide View Animation

iosswiftanimationuikituistackview

提问by Infinity James

In iOS 11 the behaviour of the hide animation within a UIStackViewhas changed, but I have been unable to find this documented anywhere.

在 iOS 11 中,隐藏动画的行为发生了UIStackView变化,但我无法在任何地方找到此文档。

iOS 10

iOS 10

iOS 10 animation

iOS 10 动画

iOS 11

iOS 11

iOS 11 animation

iOS 11 动画

The code in both is this:

两者的代码是这样的:

UIView.animate(withDuration: DiscoverHeaderView.animationDuration,
                       delay: 0.0,
                       usingSpringWithDamping: 0.9,
                       initialSpringVelocity: 1,
                       options: [],
                       animations: {
                            clear.isHidden = hideClear
                            useMyLocation.isHidden = hideLocation
                        },
                       completion: nil)

How do I restore the previous behaviour on iOS 11?

如何在 iOS 11 上恢复以前的行为?

回答by A Springham

Just had the same issue. The fix is adding stackView.layoutIfNeeded()inside the animation block. Where stackViewis the container of the items you're wishing to hide.

刚刚有同样的问题。修复是stackView.layoutIfNeeded()在动画块内添加。stackView您要隐藏的物品的容器在哪里。

UIView.animate(withDuration: DiscoverHeaderView.animationDuration,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                        clear.isHidden = hideClear
                        useMyLocation.isHidden = hideLocation
                        stackView.layoutIfNeeded()
                    },
                   completion: nil)

Not sure why this is suddenly an issue in iOS 11 but to be fair it has always been the recommended approach.

不知道为什么这会突然成为 iOS 11 中的一个问题,但公平地说,它一直是推荐的方法。

回答by ergunkocak

Swift 4 Extension:

斯威夫特 4 扩展:

// MARK: - Show hide animations in StackViews

extension UIView {

func hideAnimated(in stackView: UIStackView) {
    if !self.isHidden {
        UIView.animate(
            withDuration: 0.35,
            delay: 0,
            usingSpringWithDamping: 0.9,
            initialSpringVelocity: 1,
            options: [],
            animations: {
                self.isHidden = true
                stackView.layoutIfNeeded()
            },
            completion: nil
        )
    }
}

func showAnimated(in stackView: UIStackView) {
    if self.isHidden {
        UIView.animate(
            withDuration: 0.35,
            delay: 0,
            usingSpringWithDamping: 0.9,
            initialSpringVelocity: 1,
            options: [],
            animations: {
                self.isHidden = false
                stackView.layoutIfNeeded()
            },
            completion: nil
        )
    }
}
}

回答by Paul T.

I want to share this function that is good for hiding and showing many views in UIStackView, because with all the code I used before didn't work smooth because one needs to removeAnimation from some layers:

我想分享这个有利于隐藏和显示许多视图的函数UIStackView,因为我之前使用的所有代码都不能顺利运行,因为需要从某些图层中删除动画:

extension UIStackView {
    public func make(viewsHidden: [UIView], viewsVisible: [UIView], animated: Bool) {
        let viewsHidden = viewsHidden.filter({ 
extension UIView {
    func isHiddenAnimated(value: Bool, duration: Double = 0.2) {
        UIView.animate(withDuration: duration) { [weak self] in self?.isHidden = value }
    }
}
.superview === self }) let viewsVisible = viewsVisible.filter({
validatableButton.isHiddenAnimated(value: false)
.superview === self }) let blockToSetVisibility: ([UIView], _ hidden: Bool) -> Void = { views, hidden in views.forEach({
UIView.animate(withDuration: 0.3){
    viewInsideStackView.hidden = true //or false
}
.isHidden = hidden }) } // need for smooth animation let blockToSetAlphaForSubviewsOf: ([UIView], _ alpha: CGFloat) -> Void = { views, alpha in views.forEach({ view in view.subviews.forEach({ ##代码##.alpha = alpha }) }) } if !animated { blockToSetVisibility(viewsHidden, true) blockToSetVisibility(viewsVisible, false) blockToSetAlphaForSubviewsOf(viewsHidden, 1) blockToSetAlphaForSubviewsOf(viewsVisible, 1) } else { // update hidden values of all views // without that animation doesn't go let allViews = viewsHidden + viewsVisible self.layer.removeAllAnimations() allViews.forEach { view in let oldHiddenValue = view.isHidden view.layer.removeAllAnimations() view.layer.isHidden = oldHiddenValue } UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 1, options: [], animations: { blockToSetAlphaForSubviewsOf(viewsVisible, 1) blockToSetAlphaForSubviewsOf(viewsHidden, 0) blockToSetVisibility(viewsHidden, true) blockToSetVisibility(viewsVisible, false) self.layoutIfNeeded() }, completion: nil) } } }

回答by Alessandro Francucci

Extension to hide/show single elements

隐藏/显示单个元素的扩展

It's not 100% related, but if you're looking for a concise way to hide single UIView's elements (either in a stack view or anywhere else), you can use this simple extension I made:

它不是 100% 相关的,但是如果您正在寻找一种简洁的方法来隐藏 singleUIView的元素(在堆栈视图中或其他任何地方),您可以使用我制作的这个简单的扩展:

##代码##

I use it to conveniently hide/show elements with animation in a stack view with a single line of code. Example:

我使用它在堆栈视图中使用一行代码方便地隐藏/显示带有动画的元素。例子:

##代码##

回答by Sajjad

just add these lines of code.

只需添加这些代码行。

in Swift 4:

在 Swift 4 中:

##代码##