Reputation: 1532
I'm having some difficulties animating one of my view's layoutConstraints:
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.topLayoutConstraint?.constant = self.currentYPosition
self.layoutIfNeeded()
}, completion: nil)
Whatever the duration or the delay that I use, the animation is instantly done (my view jumps from previous position to the new one).
I've checked all the value and they are correct. I've also checked and the animation and completion are called.
Any ideas ?
EDIT:
@objc private func viewDragged(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: self.superview)
switch recognizer.state {
case .ended:
if (recognizer.direction == .Down) { // Collapsing the slide panel
currentYPosition = parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight
}
else if (recognizer.direction == .Up) { // Expanding the slide panel
// Substracting `minimumVisibleHeight` so that the dragable part is hidden behind the navigation bar
currentYPosition = -minimumVisibleHeight
}
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
break
case .began:
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
default:
self.layoutIfNeeded()
if (location.y < (parentViewHeight - minimumVisibleHeight - statusBarHeight - navBarHeight)
|| location.y > (statusBarHeight + navBarHeight)) {
currentYPosition -= HomeSlidePanelContainerView.draggingPreviousPosition - location.y
topLayoutConstraint?.constant = currentYPosition
self.layoutIfNeeded()
}
HomeSlidePanelContainerView.draggingPreviousPosition = location.y
break
}
}
Upvotes: 3
Views: 2063
Reputation: 1532
I've managed to find the solution. This might help others so I'm answering my own question.
What I was doing was something like this:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
As you can see, I'm changing a value, topLayoutConstraint
, that is a constraint on self
which is a UIView
.
Then I'm trying to animate that change by calling self.layoutIfNeeded
in an animation closure.
The thing here is that layoutIfNeeded()
applies to subviews and not the view itself. So in my case i was trying to animate the layout of self
's subviews instead of self
itself.
Changed self.layoutIfNeeded()
to self.superview?.layoutIfNeeded()
and Voilà !!
Upvotes: 9
Reputation: 1
I often use Snapkit or Masonry do autolayout, maybe you can try it.It is familiar with Apple's autolayout, it is awesome!For example sub code I use today:
UIView.animate(withDuration: 1.0, animations: {
minLabel.snp.updateConstraints { (make) in
make.top.equalTo(view.snp.centerY)
}
})
self.view.layoutIfNeeded()
Upvotes: 0
Reputation: 19602
Set the constraint before the animation block:
self.topLayoutConstraint?.constant = self.currentYPosition
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
Upvotes: 0