I want to scale+translate a view and then animate this transformation back. But CGAffineTransformInvert returns a transformation that does something different (cannot understand the logic of it).
#import <UIKit/UIKit.h>
@interface TestView : UIView {
UIView *view;
CGAffineTransform transform;
}
@end
#import "TestView.h"
#import <QuartzCore/QuartzCore.h>
@implementation TestView
- (void)testAnimation:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context {
CGAffineTransform transformInverted = CGAffineTransformInvert(transform);
[UIView beginAnimations:@"test2" context:NULL];
[UIView setAnimationDuration:3.0];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
view.transform = transformInverted;
[UIView commitAnimations];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
view = [[UIView alloc] initWithFrame:CGRectMake(150, 150, 100, 100)];
view.backgroundColor = [UIColor greenColor];
[self addSubview:view];
CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform, -150, -150);
transform = CGAffineTransformScale(transform1, (float)1/2, (float)1/2);
[UIView beginAnimations:@"test1" context:NULL];
[UIView setAnimationDuration:3.0];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(testAnimation:finished:context:) ];
view.transform = transform;
[UIView commitAnimations];
}
return self;
}
CGAffineTransformInvert
inverts the transform matrix, and returns a matrix that when multiplied by the original results in the CGAffineTransformIdentity
.
If you want to invert the translation/scale, you should track them yourself.
PS. Matrices are very complex, they don't store the translation/scale/rotation values, they are composed of several values that when multiplied by the coordinates give you the translated/scaled/rotated values, so you can't expect to invert the matrix and get a matrix with the translation, scale and rotations inverted.
You can read more about them here.
EDIT TO ANSWER YOUR COMMENT:
When working with matrices, the order of operations matters a lot, if you rotate and then translate, the result will be different than if you translate and then rotate.
To reverse the operations applied to a matrix, you should apply the opposite operations in the reverse order, in this case, to reverse this:
CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform, x1, x2);
CGAffineTransform transform2 = CGAffineTransformScale(transform1, r1, r2);
CGAffineTransform transform3 = CGAffineTransformRotate(transform2, a);
You'd need to do this:
CGAffineTransform reversed3 = CGAffineTransformRotate(transform3, -a);
CGAffineTransform reversed2 = CGAffineTransformScale(reversed3, 1/r1, 1/r2);
CGAffineTransform reversed1 = CGAffineTransformTranslate(reversed2, -x1, -x2);
[view setTransform:reversed1];
If you hadn't modified the view's transform before, you can just do:
[view setTransform:CGAffineTransformIdentity];
Which is zero rotation, zero translation, and a scale of 1.