Reputation: 1107
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?
Upvotes: 5
Views: 6712
Reputation: 2592
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.
Upvotes: 0
Reputation: 8963
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];
Upvotes: 9
Reputation: 859
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.
Upvotes: 0
Reputation: 29524
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.
Upvotes: 4