ios growth animation CGAffineTransformMakeScale moves around - iphone

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];

Related

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!

How to scale view with animation

I use the code below to scale my view when event happen. But I want the view to be enlarged or reduced with animation not directly see the scaled result. How can I achieve that effect?
view.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor)
You can use UIViewAnimations
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
view.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);
[UIView commitAnimations];
You could also use a block animation.
[UIView animateWithDuration:0.3 animations:^{
view.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor)
}];

uiview CGAffineTransform animates backwards

I have a UIView subclass which I am able to successfully use UIView animations on.
This UIView also has subviews, which I also want to be able to UIView animate.
However, it seems that whenever I create an animation and apply it to the parent view it works fine, but if I apply the animation to the child view it animates backwards.
For example, if I scale my UIView parent(self) by a factor of 2 (to double the width and height):
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration:2];
[UIView setAnimationDelay:2];
CGAffineTransform scaleTransform = CGAffineTransformScale( self.transform, 2, 2 );
self.transform = scaleTransform;
[UIView commitAnimations];
then this works fine.
But if I do the same on the child:
UIView *myObj = [[self subviews] objectAtIndex:0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration:2];
[UIView setAnimationDelay:2];
CGAffineTransform scaleTransform = CGAffineTransformScale( myObj.transform, 2, 2 );
myObj.transform = scaleTransform;
[UIView commitAnimations];
It doesn't work. What happens visually is that the child view immediately shrinks down and then after the delay scales back up to it's original size.
If I log the transform parameters it looks the same for both parent and child and I have tried setting CGAffineTransformIdentity.
Any ideas what might be the problem?
I was overriding layoutSubviews and in there I was assigning sizes/positions of the views based upon device orientation which was conflicting.doh!

Animated moving and rotating a UIView doesn't quite work

I want to create an animation that moves and rotates a UIView at the same time. I tried the following code:
[UIView beginAnimations:#"MoveAndRotateAnimation" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:kAnimationDuration];
myView.frame = newFrame;
myView.transform = CGAffineTransformMakeRotation(0.4);
[UIView commitAnimations];
The result is, that after the animation has finished the view is drawn incorrectly (some parts are not visible anymore). If I only change the frame OR the transformation for the animation, the view draws correctly. The problem only occurs if I set both the frame and transformation.
What would be the correct way to animate moving and rotating of a view at the same time?
You can't use frame, bounds, or center if you are also animating things like rotation. You need to use CGAffineTransforms for everything and concatenate them together. Like so:
CGAffineTransform transform = CGAffineTransformMakeTranslation(100,100);
transform = CGAffineTransformRotate(transform, 0.4);
[UIView beginAnimations:#"MoveAndRotateAnimation" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:kAnimationDuration];
myView.transform = transform;
[UIView commitAnimations];
Try doing it this way: (Moving left and rotating, just for example)
[UIView beginAnimations:#"MoveAndRotateAnimation" context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:kAnimationDuration];
CGPoint center = CGPointMake(-200, self.view.center.y);
self.view.transform = CGAffineTransformMakeRotation(-0.5);
self.view.center = center;
[UIView commitAnimations];
The center point locations would be the point you wish to make the view move, of course.
The problem is probably with your new frame size as compared to original frame size. View frame is a bit tricky when you rotate a frame:
Frame is in superviews coordinate system. So, when you rotate a rectangle, the new frame will be the smallest rectangle in superview's coordinate system which contains the view.
e.g. if you have a square view with frame size of (100*100) and rotate it by 45 degrees your new frame would have a size of (141*141) and if you set the frame to have a size of (100*100) you'll cut part of your view.
Look at here for better understanding of how view frame works.
You need to do this:
#pragma mark (Woblling animation)
CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-10.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(10.0));
self.view .transform = leftWobble; // starting point
[UIView beginAnimations:#"wobble" context:self.view ];
[UIView setAnimationRepeatAutoreverses:YES]; // important
[UIView setAnimationRepeatCount:11];
[UIView setAnimationDuration:1.00];
//[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(wobbleEnded:finished:context:)];//should be same as written
self.view .transform = rightWobble; // end here & auto-reverse
[UIView commitAnimations];
and then implement these methods. They are necessary to keep your view in the same position after rotation.
- (void) wobbleEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
if ([finished boolValue]) {
UIView* item = (UIView *)context;
item.transform = CGAffineTransformIdentity;
}
}
Use this method if you are using navigation and when you navigate from one view to another, then your view would be at the same place.else leave this method:
- (void)viewWillAppear:(BOOL)animated
{
UIView* item = self.view;
item.transform = CGAffineTransformIdentity;
}
I had the same problem but did some experiments and came up with this solution.

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];
}