I've noticed that in iOS 10 Beta 5 (about to try Beta 6), AutoLayout constraint animation behaves a bit differently.
For example, this approach does not work the same as it did in previous iOS releases:
[view addConstraints:@[constraints...]];
[view setNeedsUpdateConstraints];
[view layoutIfNeeded];
[UIView animateWithDuration:...
{
/* adjust constraint here... */
[view layoutIfNeeded]; // Only the adjusted constraints since previous layoutIfNeeded() call should animate change with duration.
} completion:{ ... }];
... In my testing, the constraints initially added with addConstraints()
will also animate in iOS 10 with the UIView animateWithDuration()
block... which is causing some funky/undesirable behavior so far.
For example, setting the left/right constraints in the array (but the vertical constraints in the block) causes the entire view to animate onto the screen diagonally with this approach... which is totally incorrect.
Does anyone know how to do this correctly for both iOS 9 (and below), as well as 10?
Try calling layoutIfNeeded
on the view's superview, instead of the view itself.
--
I had a similar problem, my view was supposed to animate from the top at a 0 height, downward to a > 0 height (i.e. (0, 0, 320, 0) to (0, 0, 320, 44)).
Using Xcode 8 with iOS 10, the animation behavior was much different. Instead of animating downward from the top, the view animates up & down from the vertical center of the destination frame.
I fixed this by, instead of calling layoutIfNeeded
on the view itself, calling it on the view's superview. Somehow, the behavior was restored.
Hope it helps!
Helpful comment by @Ramiro:
According to the documentation, layoutIfNeeded
lays out the subviews (but doesn't contemplate the current view itself). So, in order to update the current view lay out, you need to call layoutIfNeeded
from the super view.
In below method :
[super viewDidLoad];
Write this line:
[self.view layoutIfNeeded];
I made a small test changing H and V of a small red view:
self.red_POS_H = NSLayoutConstraint.constraints(withVisualFormat: "H:|-90-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)
self.red_POS_V = NSLayoutConstraint.constraints(withVisualFormat: "V:|-30-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)
self.view.addConstraints(self.red_POS_V!)
self.view.addConstraints(self.red_POS_H!)
and animated it:
// we hope is only one:
let currV = self.red_POS_V![0]
let currH = self.red_POS_H![0]
UIView.animate(withDuration: 3) {
// Make all constraint changes here
currV.constant = 100
currH.constant = 300
self.view.layoutIfNeeded() // Forces the layout of the subtree animation block and then captures all of the frame changes
}
red view moved correctly, if You comment out single line in animation, it does work, horizontally or vertically.
Small project avalable, if You need it.