This question already has an answer here:
- How do I animate constraint changes? 13 answers
I am trying to animate up some views so that they are blocked by the giant keyboard in landscape. It works well if I simply animate the frames, but others have suggested that this is counter-productive and I should be updating the NSLayoutConstraints instead. However, they don't seem to be animatable. Has anyone gotten them to work with success?
//heightFromTop is an NSLayoutConstraint referenced from IB
[UIView animateWithDuration:0.25 animations:^{
self.heightFromTop.constant= 550.f;
}];
The result is an instant jump to the height in question.
The Apple's suggested way is a little bit different (See example in "Animating Changes Made by Auto Layout" section). First you need to call layoutIfNeeded before the animation. Then add your animation stuff inside the animation block and then call layoutIfNeeded at the end again. For the guys like me who are transitioning to autolayout, its more similar way to previous animations that we were doing with the frames inside animation blocks. We just need to call layoutIfNeeded twice - before animations and after animations:
I was having a similar problem and this thread was a great help to get past it.
The answer from erurainon put me on the right track, but I'd like to propose a slightly different answer. The suggested code from erurainon did not work for me, as I still had a jump instead of an animated transition. The link provided by cnotethegr8 gave me the working answer:
Auto Layout Guide https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (all the way to the bottom of the page).
A few differences from the answer by erurainon:
This will adhere to the pattern suggested by Apple in the link above.
An example
I wanted to animate a particular view, closing or expanding it at the click of a button. Since I'm using autolayout and didn't want to hard code any dimensions (in my case height) in the code, I decided to capture the height in viewDidLayoutSubviews. You need to use this method and not viewWillAppear when using autolayout. Since viewDidLayoutSubviews may be called many times, I used a BOOL to let me know about the first execution for my initialization.
Resize full action snippet
Resize small action snippet
You can use animateWithDuration instead of transitionWithView if you wish.
Hope this helps.
I tried @Centurion's approach, but somehow my view would animate to a wrong frame if it's loaded from the storyboard. The issue goes away if I replace the first
layoutIfNeeded
withupdateConstraintsIfNeeded
, though I have no idea why. If anyone can give an explanation it'd be much appreciated.Just follow this exact pattern:
where
myView
is the view whereself.heightFromTop
was added to. Your view is "jumping" because the only thing you did in the animation block was to set the constraint, which does not cause layouts immediately. In your code, the layout happens on the next run loop after you setheightFromTop.constant
, and by that time you are already outside the scope of the animation block.In Swift 2: