Animation not Shown When Calling it First Time

2019-07-18 21:16发布

问题:

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 of scrollview 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 of scrollview 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?

回答1:

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

Blockquote

-performSelector:withObject:afterDelay: with a delay of 0.

It will solve your problem.



回答2:

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 set frame 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, the frame may get reset.

There are two solutions:

  1. 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 the constant property within an animation block.

  2. You can also simply disable autolayout.