I have one simple animation:
- (void)showMenu
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.scrollView.frame = CGRectMake(296, -150, 432, 356);
[self.buttonMenu setImage:[UIImage imageNamed:@"menu_arrow_up.png"] forState:UIControlStateNormal];
[self.view bringSubviewToFront:self.scrollView];
[UIView commitAnimations];
}
When I call this animation the first time, just the image of my button changes, the position of my scrollview does not change.
Everything works correctly, after I called my showMenu
method twice.
- I call
showMenu
. the image of the button changes. position ofscrollview
not - I call another method to reset everything. image of button changes. position of
scrollview
not - I call
showMenu
. the image of the button changes. position ofscrollview
changes - from now on it works every time I call
showmenu
the second method is closeMenu
:
- (void)closeMenu
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.scrollView.frame = CGRectMake(296, -317, 432, 356);
[self.buttonMenu setImage:[UIImage imageNamed:@"menu_arrow_down.png"] forState:UIControlStateNormal];
[UIView commitAnimations];
}
So why does it work just when I click it twice?
If you have autolayout turned on, you may want to wary about changing the
frame
of a view. Unfortunately, when the constraints are reapplied (which triggered by a myriad of seemingly innocuous actions, such as setting a text label, etc.), your manually setframe
will be replaced with values governed by the constraints.You're probably not seeing this problem manifest itself the second time time you call this routine because you're probably not doing anything immediately thereafter that causes constraints to be reapplied. Even with autolayout on, you can sometime change a
frame
manually, and it will work, but as soon as constraints are reapplied, theframe
may get reset.There are two solutions:
If using auto layout, you can animate the changing of constraint constants. See the latter part of this answer for an example of how to create an
IBOutlet
for constraint and then changing theconstant
property within an animation block.You can also simply disable autolayout.
I had the same problem when i perform a UIAnimation and simultaneously adding a UITableView programmatically. The frame of UIView changes but it will not update in display. To solve this problem call your method using
-performSelector:withObject:afterDelay: with a delay of 0.
It will solve your problem.