Reputation: 936
I have a keyboard notification and I want it so that when it goes off, the placeholder view animates to the left edge of the search bar.
Below is what I use to call the animation which is asynchronous with the keyboard opening. Currently, the view moves to the spot I want it to, however it's as if it's teleporting there rather than animating.
DispatchQueue.main.async {
if isKeyboardShowing {
UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
}, completion: { (completed) in
})
}
}
Any Suggestions?
Upvotes: 2
Views: 1514
Reputation: 8968
The animation with constraints could be a little bit tricky. First you need to adjust desired constraints, outside of the animation closure:
NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
Since constraint changes could cause other views change their position, you need ask superview (in the most cases the VC-view) to layout its subviews within the animation closure:
UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Therefore the superview adjusts subviews positions for you within the animation block.
Upvotes: 4
Reputation: 763
In order to animate a NSLayoutConstraint
you need to put setNeedsLayout()
in the animation block. You should then move the
NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
to above the animation block like so:
NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.layoutIfNeeded()
}, completion: { (completed) in
})
Hope that helps!
Upvotes: 1