iPhone: How to commit two animations after another - iphone

This is an absolute beginner's question (sorry), but I was wondering how to commit one animations and once it has ended to start another one. Imagine having an image moved from x=0 to x=300. Then you want to do animate the same image again, but this time from x=300 to x=330 so that it disappears from the screen.
The following code will only do the animation from x=300 to x=330 and will not commit the animation x=0 to x=300. I'm sure I don't get the concept of commitAnnimation and that this is obvious, but how would I do two animations after one another?
I know I could move the image straightaway to 330, but I don't want this as I need the first animation (x 0 - 300) to be in sync with another animation.
Here is my (wrong) code:
[UIView beginAnimations:#"shadowMove" context:nil]; // Begin animation
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[imageView setFrame:CGRectOffset([imageView frame], 300, 0)];
[UIView commitAnimations]; // End animations
// Second Animation
[UIView beginAnimations:#"shadowMoveRestAway" context:nil]; // Begin animation
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[imageView setFrame:CGRectOffset([imageView frame], 330, 0)]; // Move imageView off screen
[UIView commitAnimations]; // End animations

Use the delegate method
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
to start something else when the first animation has finished. So put what you want to do next inside the animationDidStop:finished:context method, remember that the iphone is an event driven environment so linear code like you have above will simply kick off each animation at almost the same time.
EDIT:
I forgot to add that you need to set the animation delegate as well otherwise you won't get the event when the first one stops - see below;
Here's a full version of your code with the change - I'm using the abbreviated animationDidStop delegate as that's easier to understand and fine for this example.
[UIView beginAnimations:#"shadowMove" context:nil]; // Begin animation
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(myFirstAnimationDidStop)];
[imageView setFrame:CGRectOffset([imageView frame], 300, 0)];
[UIView commitAnimations]; // End animations
Then you just need a new method like this;
-(void) myFirstAnimationDidStop {
// Second Animation
[UIView beginAnimations:#"shadowMoveRestAway" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[imageView setFrame:CGRectOffset([imageView frame], 330, 0)];
[UIView commitAnimations];
}
And for completeness, in your interface (.h) file you should add;
-(void) myFirstAnimationDidStop;
#selector is easy, it's just a way of pointing to another method - hopefully this example clarifies that.

Related

how to hook UIView's animation?

I want to send my own message during UIView's animation process.
For example:
myView.alpha = 1.0;
[UIView animateWithDuration:2.0f animations:^{myView.alpha = 0.0;} completion:^(BOOL isFinished){}];
I want to send the message when iOS render the specific alpha's animation frame.
- (void) alphaChangedTo:(float) val
{
[sendMyOwnMessage:val];
}
as the animation is carried out by the iOS system, can I hook the function to finish my task?
Thanks!
Have you tried animation code block??
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:1.0];
[sendMyOwnMessage:val];
[UIView commitAnimations];
I am not sure if this is what you are looking for.. but I hope this helps.. Cheers!! Happy Coding.

Trouble with UIView Animations - performing the same animation more than once doesn't work

I need to flip a card and then flip it back. I have written code to do that with no trouble. The trouble comes because users can flip this card back and forth as many times as they want, and it seems that the effect is cumulative. On the second try, the card spins like a top. I'm not completely surprised, as there only seems to be a way to add animation, not clear one from the view. Is there a way to 're-set' a UIView of any animations I had previously committed? Is there a way to capture it and re-use it without committing a new one? Or am I missing something obvious? This is my code:
if (self.flipped) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self
cache:YES];
[imageView removeFromSuperview];
[UIView commitAnimations];
self.flipped = NO;
} else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self
cache:YES];
[self addSubview:imageView];
[UIView commitAnimations];
self.flipped = YES;
}
Thanks for reading.
To cancel all ongoing animations:
#import <QuartzCore/QuartzCore.h>
...
[view.layer removeAllAnimations];
To start a new animation that kills existing animations, if any, and starts the movement from wherever the view currently is — which I think is what you want:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
... and the rest of it ...
[UIView commitAnimations];
Hopefully one of those will solve your problem.
Whatever your "self" is, put it in a containing view called foo, and then change your setAnimation... line to this:
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:foo
cache:YES];

animation effects : leaf falling down to ground

Need to figure some transformation codes to implement falling down naturally just like leaves falling down from tree.
Here are some codes, fly from one place to another place with some rotation angle.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:5.0];
[UIView setAnimationDelegate:self];
//[UIView setAnimationRepeatCount:1e100f]; //coutless
[UIView setAnimationRepeatCount:1]; // 1 time
//[UIView setAnimationRepeatAutoreverses:YES];
leaf2.frame = CGRectMake(LEAF2_X, LEAF2_Y, LEAF2_W, LEAF2_H);
leaf2.transform = CGAffineTransformMakeRotation(ANGLE);
[UIView commitAnimations];
See if the next 2 questions help:
What is the best way to make a bouncing ball animation with infinite loop on iPhone?
Mimic UIAlertView Bounce?

how to implement an iPhone view transition animation with both flipping and scaling?

how can I implement the animation we see in the iPhone Music app's coverflow screen? when you click on a small view, it flips and scales up to another view? how can I do this? I can use core animation to flip and scale a view, but how can I do the transition to another view? thanks
You need an UIView as Container for the two UIViews (frontside/backside) and then remove/add these from/to the container as subviews while doing the animations in between:
UIView *flipContainer;
UIView *frontSide;
UIView *backSide;
//...
-(void)turnUp
{
[backSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:frontSide];
}
-(void)turnDown
{
[frontSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1, 1);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:backSide];
}
I'm trying the exact code you are doing - I get a zoom effect but no turn over. The only difference is that right before the turnUp code I add the flipContainer (with back showing) so then it can be flipped over.
// construct animation container
self.flipContainer = [[FlipContainer alloc] init];
[self.flipContainer.view setFrame:CGRectMake(clickedSquareX, clickedSquareY, 200, 200)];
[self.flipContainer.view addSubview:self.backside.view];
// add animation container
[self.myParentView.view addSubview:self.flipContainer.view];
// PROCEED to your turnUp code
The reason I'm doing this is I have a bunch of images in a horizontal UIScrollView and so to 'simulate' a 200x200 image flipping over and zooming to show detail I add my flipContainer with the backside showing the exact image over the exact spot of the pressed image. It should work shouldn't it? A bit confusing to me is the first line of your turnUp code you do:
[backSide removeFromSuperview];
..which would remove the view I just added.
I'm not sure if this is the right spot to put this question in - sorry if it isn't!

iPhone: transitioning views with Core Animation

On the Mac, the best way for a simple cross-fade transition of views (without any custom keyframe timing) is to do something such as the following excerpt:
[[self animator] replaceSubview:aView with:bView];
Unfortunately the animator property isn't available on the iPhone. What's the best bet of doing this on the iPhone? Is it setting alpha channels on each view? Sample code would be excellent.
Thanks.
The basic way to animate views on the iphone is to use the UIView beginAnimations and commitAnimations calls. They allow you to modify the animatable properties of a view and have those changes animated.
For instance I have a custom view that is hidden and shown using this approach:
- (void) showAView:(CustomAView *)aView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
aView.frame = CGRectMake(0.0f, 110.0f , aView.frame.size.width, aView.frame.size.height);
[UIView commitAnimations];
}
- (void) hideAView:(CustomAView *)aView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
aView.frame = CGRectMake(0.0f, self.view.frame.size.height, aView.frame.size.width, aView.frame.size.height);
[UIView commitAnimations];
}
By wrapping the frame property change in the UIView beginAnimations/commitAnimations the change has a standard animation applied to it.
You can add additional properties to the animation by using UIView animation class methods eg.
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];