How do you rotate UIView, UIImageView or CALayer animated 360˚? - iphone

How do you rotate UIView, UIImageView or CALayer animated 360 degress without using OpenGL ES?

#import <QuartzCore/QuartzCore.h>
CABasicAnimation *fullRotation;
fullRotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
fullRotation.fromValue = #(0.0);
fullRotation.toValue = #((360.0 * M_PI)/180.0);
fullRotation.duration = 3.5f;
fullRotation.repeatCount = MAXFLOAT;
[view.layer addAnimation:fullRotation forKey:#"rotation-animation"];
If you want to change the anchor point it to rotates around then you can do
CGRect frame = view.layer.frame;
self.anchorPoint = CGPointMake(0.5, 0.5); // rotates around center
self.frame = frame;

Presumably you mean animate rotating a UIImage around a full 360°? In my experience, the way to accomplish a full circle rotation is to chain multiple animations together:
- (IBAction)rotate:(id)sender
{
[UIView beginAnimations:#"step1" context:NULL]; {
[UIView setAnimationDuration:1.0];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
[imageView.transform = CGAffineTransformMakeRotation(120 * M_PI / 180);
} [UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
if ([animationID isEqualToString:#"step1"]) {
[UIView beginAnimations:#"step2" context:NULL]; {
[UIView setAnimationDuration:1.0];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
imageView.transform = CGAffineTransformMakeRotation(240 * M_PI / 180);
} [UIView commitAnimations];
}
else if ([animationID isEqualToString:#"step2"]) {
[UIView beginAnimations:#"step3" context:NULL]; {
[UIView setAnimationDuration:1.0];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationDelegate:self];
imageView.transform = CGAffineTransformMakeRotation(0);
} [UIView commitAnimations];
}
}
I've left the easeIn/easeOut curve (instead of linear) in place, so you can see the individual animations.

Related

ios growth animation CGAffineTransformMakeScale moves around

I am animating a tree that grows. Like a Tree, I want my UIImage to stay in the same place, so that when I scale it up it appears to grow.
Right now its jumping around, i.e. its growing from the centre - I need it to grow from the bottom.
Is there a way to set the origin/base of the animation. So the scale animation works from the bottom.
Hope that makes sense. here is my code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
tree.transform = CGAffineTransformMakeScale(1.0f, 1.25f);
[UIView commitAnimations];
You may wish to look at the CALayer class for this and set the anchorPoint to the centerbottom
- (void)viewDidLayoutSubviews
{
self.outletTestView.layer.anchorPoint = CGPointMake(0.5, 1.0);
self.outletTestView.layer.position = CGPointMake(100, 300);
}
Don't forget to include:
#import <QuartzCore/QuartzCore.h>
And use for the scaling:
CGAffineTransform CGAffineTransformScale ( CGAffineTransform t, CGFloat sx, CGFloat sy );
Like so:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
tree.transform = CGAffineTransformScale(tree.transform, 1.0f, 1.25f);
[UIView commitAnimations];

How Do You Combine Scale and Translation Animation

I am attempting to do an UIView animation where my image starts at the top left of the screen and expands to the original size and place in the middle of the screen. So far I have been able to make it do this separately but when I try to combine these animations it will only do the scale animation.
Is there a way I can make this work with Scale and Translation at the same time?
Here is what I have so far:
CGAffineTransform setpointTrans = CGAffineTransformMakeTranslation(-200.0f, -200.0f);
CGAffineTransform setpointScale = CGAffineTransformMakeScale(0.0f, 0.0f);
_RSEImage.transform = CGAffineTransformConcat(setpointTrans, setpointScale);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGAffineTransform scaleTrans = CGAffineTransformMakeScale(1.0f, 1.0f);
CGAffineTransform lefttorightTrans = CGAffineTransformMakeTranslation(0.0f,0.0f);
_RSEImage.transform = CGAffineTransformConcat(scaleTrans, lefttorightTrans);
[UIView commitAnimations];
Ok I figured it out, here is what I changed:
_RSEImage.transform = CGAffineTransformMakeScale(0.0f, 0.0f);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGAffineTransform scaleTrans = CGAffineTransformMakeScale(1.0f, 1.0f);
CGAffineTransform lefttorightTrans = CGAffineTransformMakeTranslation(200.0f,200.0f);
_RSEImage.transform = CGAffineTransformConcat(scaleTrans, lefttorightTrans);
[UIView commitAnimations];
You can use this, animation blocks, also (from iOS4):
[UIView animateWithDuration: 5
delay: 0
options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
animations:^{_RSEImage.center = CGPointMake(300, 300) ; _RSEImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 2.0, 2.0);}
completion:^(BOOL finished) { }
];
Relevant official doc here: link
Nice tutorial there: link
Hope it helps!

Blink hidden and using blocks

I have the method:
- (void)blinkView:(UIView *)view
{
view.layer.opacity = 0.0f;
view.hidden = NO;
[UIView beginAnimations:#"Blinking" context:nil];
[UIView setAnimationRepeatCount:1.0];
[UIView setAnimationDuration:0.6f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view.layer.opacity = 1.0f;
[UIView commitAnimations];
}
How can i write this code with blocks, and how i must implement method with reverse effect (hide uiview with blink) ?
[UIView transitionWithView: view
duration:0.6f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{ view.layer.opacity = 1.0f; }
completion:NULL];
or
[UIView transitionWithView: view
duration:0.6f
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{ view.layer.opacity = 1.0f; }
completion:NULL];
You can set the repeat count by recursively calling the animation block (see here).
Hope it will help you.
You can use UIView's setAnimationDelegate: and setAnimationDidStopSelector:
[UIView beginAnimations:#"Blinking" context:nil];
[UIView setAnimationRepeatCount:1.0];
[UIView setAnimationDuration:0.6f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view.layer.opacity = 1.0f;
[UIView commitAnimations];
- (void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
// add your final code here : you can give new animation effect here.
}
Or try animateWithDuration (available only in iOS 4 or later)
[UIView animateWithDuration:0.6f
animations:^{
view.layer.opacity = 1.0f;
}
completion:^(BOOL completed){
// add your final code here : you can give new animation effect here.
}
];

Spawning infinite UIImageViews without name collisions

iPad app. OS 4.2.
I have a button that, when pressed, calls this function that creates a UIImageView and animates it (and calls a second animation block). I created another button that calls the same function and passes different locations and different URL to a graphic.
I'm starting to get glitches—the first graphic spawned from the first button has the locations passed from the second button. This is probably due to the fact that I am not dynamically naming the UIImageView and getting collisions from that.
So how do I dynamically create and name any infinite number of UIImageViews? Especially since, to reference the UIImageView in two functions, it needs to be declared outside of the functions.
-(void)makeSoundEffectWordAppear:(NSString *)imageName:(int)startingX:(int)startingY:(int)endingX:(int)endingY{
myImage = [UIImage imageNamed:imageName];
[testWord setImage:myImage];
testWord = [[[UIImageView alloc] initWithFrame:CGRectMake(startingX,startingY,myImage.size.width,myImage.size.height)] autorelease];
[self.view addSubview:testWord];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView beginAnimations:#"moveWord" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeWord:finished:context:)];
//[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationBeginsFromCurrentState:YES];
testWord.transform = CGAffineTransformMakeScale(1, 1);
testWord.center = CGPointMake(endingX,endingY);
testWord.alpha=1;
[UIView commitAnimations];
}
- (void)fadeWord:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
[UIView beginAnimations:#"makeWordFade" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDelay:5];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView setAnimationDuration:1];
[UIView commitAnimations];
}
You have a single pointer to testWord rather than a pointer for each instance. You should be using the context property of animations to pass in the specific UIImageView you want to fade away:
-(void)makeSoundEffectWordAppear:(NSString *)imageName:(int)startingX:(int)startingY:(int)endingX:(int)endingY{
UIImage *myImage = [UIImage imageNamed:imageName];
UIImageView *testWord = [[[UIImageView alloc] initWithImage:myImage] autorelease];
CGRect frame = [testWord frame];
frame.origin.x = startingX;
frame.origin.y = startingY;
[testWord setFrame:frame];
[self.view addSubview:testWord];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView beginAnimations:#"moveWord" context:testWord];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeWord:finished:context:)];
//[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationBeginsFromCurrentState:YES];
testWord.transform = CGAffineTransformMakeScale(1, 1);
testWord.center = CGPointMake(endingX,endingY);
testWord.alpha=1;
[UIView commitAnimations];
}
- (void)fadeWord:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
UIImageView *testWord = (UIImageView *)context;
[UIView beginAnimations:#"makeWordFade" context:context];
[UIView setAnimationDelegate:self];
[UIView setAnimationDelay:5];
testWord.alpha=0;
testWord.transform = CGAffineTransformMakeScale(.5, .5);
[UIView setAnimationDuration:1];
[UIView commitAnimations];
}

IPHONE - fade in and fade out of a UIImageView with different times

I would like to do a fade in and out of a UIImageView using different times, let's say, using the following parameters:
t = 0 ... UIImageView's alpha = 0
t = 0.5s ... UIImageView's alpha = 0.7
t = 0.7s ... UIImageView's alpha = 0
Is this possible to do with CAAnimation or other method?
How can that be done?
thanks for any help!
if (imgDefault.alpha == 0.0) {
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration: 3.0];
[UIView setAnimationDelegate: self];
imgDefault.alpha = 1.0;
[UIView commitAnimations];
}
else {
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration: 3.0];
[UIView setAnimationDelegate: self];
imgDefault.alpha = 0.0;
[UIView commitAnimations];
}
hope it helps
You should probably look into CAKeyframeAnimation. It'll let you set values for multiple time points.
UIView has a setAnimationDidStopSelector: method which you can use. Simply setup your fade in animation using a beginAnimations block and set the didStop selector to another method which contains only the fade out animation block. Each of these animation blocks can have different animation durations.
Something like this:
[UIView beginAnimations:next context:context];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeOut:finished:context:)];
myView.alpha = 0.7;
[UIView commitAnimations];
-(void)fadeOut:(NSString*)animationID finished:(BOOL)finished context:(void*)context {
[UIView beginAnimations:nil context:context];
[UIView setAnimationDuration:0.2];
myView.alpha = 0.0;
[UIView commitAnimations];
}