UIStackView Скрыть вид анимации
В iOS 11 поведение анимации hide в UIStackView
изменилось, но я не смог найти это документально.
iOS 10
![iOS 10 animation]()
iOS 11
![iOS 11 animation]()
Код в обоих случаях:
UIView.animate(withDuration: DiscoverHeaderView.animationDuration,
delay: 0.0,
usingSpringWithDamping: 0.9,
initialSpringVelocity: 1,
options: [],
animations: {
clear.isHidden = hideClear
useMyLocation.isHidden = hideLocation
},
completion: nil)
Как восстановить предыдущее поведение на iOS 11?
Ответы
Ответ 1
Просто была такая же проблема. Исправление заключается в добавлении 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)
Не уверен, почему это внезапно стало проблемой в iOS 11, но, честно говоря, это всегда был рекомендуемый подход.
Ответ 2
Расширение 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
)
}
}
}
Ответ 3
Расширение, чтобы скрыть/показать отдельные элементы
Это не связано на 100%, но если вы ищете краткий способ скрыть отдельные элементы UIView
(либо в виде стека, либо где-либо еще), вы можете использовать это простое расширение, которое я сделал:
extension UIView {
func isHiddenAnimated(value: Bool, duration: Double = 0.2) {
UIView.animate(withDuration: duration) { [weak self] in self?.isHidden = value }
}
}
Я использую его для удобного скрытия/отображения элементов с анимацией в виде стека с помощью одной строки кода. Пример:
validatableButton.isHiddenAnimated(value: false)
Ответ 4
Я хочу поделиться этой функцией, которая хороша для сокрытия и отображения многих представлений в UIStackView
, потому что со всем кодом, который я использовал прежде, не работал гладко, потому что нужно удалить анимацию из некоторых слоев:
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)
}
}
}
Ответ 5
просто используйте:
UIView.animate(withDuration: 0.3){
viewInsideStackView.hidden = true //or false
}