Moving an object without animating it in an animation block
I'm animating a bunch of buttons so they move to the left of the sc开发者_运维百科reen then they should magically move to the right of the screen. I do this by calling:
[NSTimer scheduledTimerWithTimeInterval:0.20 target:self selector:@selector(moveTheButtons) userInfo:nil repeats:YES];
in viewDidLoad.
They animate quite happily to the left, but then they animate back to the right. I just want them to disappear and reappear to the right-off-screen. Because I'm new I assumed that since it was after the commitAnimations call that it wouldn't animate. I think the problem is that the animations actually 'commit' after the moveTheButtons function returns, but I can't think of an elegant (or standard) way around this.
How do I move the UIButton off screen without animating it, preferably still in the moveTheButtons function?
As you can probably infer, I'm new to animations on the iPhone, so if you see any other mistakes I'm making feel free to give me some pointers.
-(void)moveTheButtons{
NSLog(@"moveTheButtons");
[UIView beginAnimations:@"mov-ey" context:cloudA];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
cloudA.center = CGPointMake(cloudA.center.x-pos.x,cloudA.center.y);
[UIView commitAnimations];
if(cloudA.center.x < -100){
//I don't want to animate this bit.
cloudA.center = CGPointMake(550,cloudA.center.y);
}
//NSLog(@"cloudA.center.x %f", cloudA.center.x);
}
You can temporarily turn off the implicit animations of properties within an animation block using the +[UIView setAnimationsEnabled:]
method. This can be very useful in many use cases.
Do something like this:
-(void)moveTheButtons {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
CGPoint center = CGPointMake(cloudA.center.x - pos.x, cloudA.center.y);
if (center.x < -100) {
[UIView setAnimationsEnabled:NO];
cloudA.center = CGPointMake(550, center.y);
[UIView setAnimationsEnabled:YES];
} else {
cloudA.center = center;
}
[UIView commitAnimations];
}
As a side note; there is no need to give the animation a name, or a context, unless you actually use a delegate that responds to delegate methods. Just pass nil
, and NULL
as I have done in this example.
Precalculate the point , invert the order and return before animating the block.
You are unconditionally committing an animation to the engine in all cases.
-(void)moveTheButtons{
NSLog(@"moveTheButtons");
CGPoint mypoint = CGPointMake(cloudA.center.x-pos.x,cloudA.center.y);
if(cloudA.center.x < -100){
//I don't want to animate this bit.
cloudA.center = CGPointMake(550,cloudA.center.y);
return;
}
[UIView beginAnimations:@"mov-ey" context:cloudA];
[UIView setAnimationDuration: .20];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
cloudA.center = mypoint;
[UIView commitAnimations];
}
Theres a style point about using a return rather than if/else but you can form your own opinion.
Cheers
精彩评论