vertical how buttons ios swift animation uikit uistackview

ios - how - stackview buttons



UIStackView Ocultar Ver AnimaciĆ³n (5)

Extensión Swift 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 ) } } }

En iOS 11, el comportamiento de la animación oculta dentro de UIStackView ha cambiado, pero no he podido encontrar esto documentado en ningún lado.

iOS 10

iOS 11

El código en ambos es este:

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

¿Cómo restauro el comportamiento anterior en iOS 11?


Quiero compartir esta función que es buena para ocultar y mostrar muchas vistas en UIStackView , porque con todo el código que usé antes no funcionó bien porque uno necesita eliminar la animación de algunas capas:

extension UIStackView { public func make(viewsHidden: [UIView], viewsVisible: [UIView], animated: Bool) { let viewsHidden = viewsHidden.filter({ $0.superview === self }) let viewsVisible = viewsVisible.filter({ $0.superview === self }) let blockToSetVisibility: ([UIView], _ hidden: Bool) -> Void = { views, hidden in views.forEach({ $0.isHidden = hidden }) } // need for smooth animation let blockToSetAlphaForSubviewsOf: ([UIView], _ alpha: CGFloat) -> Void = { views, alpha in views.forEach({ view in view.subviews.forEach({ $0.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) } } }


Solo tuve el mismo problema. La solución es agregar stackView.layoutIfNeeded() dentro del bloque de animación. Donde stackView es el contenedor de los elementos que desea ocultar.

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)

No estoy seguro de por qué esto es repentinamente un problema en iOS 11, pero para ser justos, siempre ha sido el enfoque recomendado.


Solo usa:

UIView.animate(withDuration: 0.3){ viewInsideStackView.hidden = true //or false }


Extensión para ocultar / mostrar elementos individuales

No está 100% relacionado, pero si está buscando una manera concisa de ocultar elementos individuales de UIView (ya sea en una vista de pila o en cualquier otro lugar), puede usar esta extensión simple que hice:

extension UIView { func isHiddenAnimated(value: Bool, duration: Double = 0.2) { UIView.animate(withDuration: duration) { [weak self] in self?.isHidden = value } } }

Lo uso para ocultar / mostrar convenientemente elementos con animación en una vista de pila con una sola línea de código. Ejemplo:

validatableButton.isHiddenAnimated(value: false)