I'm trying to have a simple slide-down-from-top animation using auto layout (with the help of SnapKit
).
Below is the code I use to generate a view, set its constraints and force a reload (thus display) of said view. In the same code cope I change the top constraint to a different value and call layoutIfNeeded
in an animation block.
What happens instead though is that the view is displayed at the intended position without any animations whatsoever.
Here is the code called in a method after a short delay (for other purposes):
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
self.view.addSubview(view)
view.backgroundColor = .black
view.snp.makeConstraints { (make) -> Void in
make.left.right.equalToSuperview()
make.height.equalTo(200)
make.bottom.equalTo(self.view.snp.top) // Pin view to top to prepare slide-down animation
}
view.setNeedsLayout()
view.layoutIfNeeded()
view.snp.updateConstraints { (make) -> Void in
make.bottom.equalTo(self.view.snp.top).offset(200)
}
view.setNeedsLayout()
UIView.animate(withDuration: 5, animations: {
view.layoutIfNeeded()
})
})
Thanks to In Swift, how do I animate a UIView with auto-layout like a page sliding in? I found the culprit.
Although I don't 100% understand why this is, but layoutIfNeeded
needs to be called from the superview, not the view itself.
So calling self.view.layoutIfNeeded()
is the correct way. Note that view
is the currently being added UIView
, whereas self.view
is the superview, where view
is being added to.