Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setFrame in UIView animation doesn't move, only snaps in place

In my viewDidLoad method I place a button off to the left of the view, off screen.

Then I use these two methods to animate it:

-(void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [self showButton];
}

And the method:

-(void) showButton {
    [myButton setTitle:[self getButtonTitle] forState:UIControlStateNormal];

    // animate in
    [UIView beginAnimations:@"button_in" context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDone)];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [myButton setFrame:kMyButtonFrameCenter]; // defined CGRect
    [UIView commitAnimations];
}

The button immediately appears and does not animate. Further, the animationDone selector is called immediately.

Why doesn't it animate my button into the screen?

EDIT: This has to have something to do with trying to start an animation while in viewDidAppear...

like image 989
TigerCoding Avatar asked Jul 20 '11 13:07

TigerCoding


People also ask

Does UIView animate run on the main thread?

The contents of your block are performed on the main thread regardless of where you call [UIView animateWithDuration:animations:] . It's best to let the OS run your animations; the animation thread does not block the main thread -- only the animation block itself.

Is UIView animate asynchronous?

UIView. animate runs on the main thread and is asynchronous.


2 Answers

I tried your animation code and it works fine.

Where do set the initial frame of the button? Is it possible that you mistakenly set the button's frame to kMyButtonFrameCenter before you start the animation? That would explain why the animationDone selector is called immediately.

Here is the code that works:

-(void) showButton {
    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [myButton setTitle:@"test" forState:UIControlStateNormal];
    myButton.frame = CGRectMake(-100.0, 100.0, 100.0, 30.0);
    [self.view addSubview:myButton];

    // animate in
    [UIView beginAnimations:@"button_in" context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDone)];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [myButton setFrame:CGRectMake(100.0, 100.0, 100.0, 30.0)]; 
    [UIView commitAnimations];
}

As you see I did not change anything in your animation code. So I think the problem is the button's frame.

A bit off-topic: If you don't have build your app for iOS < 4 you might want to have a look at UIView's "animation with blocks" that came with iOS 4.0.

[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^void{myButton.frame = kMyButtonFrameCenter} completion:^(BOOL completed){NSLog(@"completed");}];

=== EDIT ===

After reading your comment, it seems that my suspicion is not correct. inspire48 points in the right direction with his answer. You should put the placement of the button inside the viewDidAppear method or in the showButton method to make sure that the button is placed outside the screen before you call the animation

like image 80
joern Avatar answered Oct 20 '22 19:10

joern


Put the animation call in viewDidAppear. viewDidLoad is used for more data-type setup. Any visual effects such as animations should go in viewDidAppear. You've confirmed this—it works if you wait a bit.

like image 35
FeifanZ Avatar answered Oct 20 '22 18:10

FeifanZ