0

ビューを拡大縮小して変換してから、この変換をアニメートして戻したいと思います。ただし、CGAffineTransformInvertは、別のことを行う変換を返します(そのロジックを理解できません)。

#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;
}
4

3 に答える 3

5

CGAffineTransformInvert変換行列を反転し、元の結果を乗算すると結果が得られる行列を返しますCGAffineTransformIdentity

翻訳/スケールを反転したい場合は、自分で追跡する必要があります。

PS。マトリックスは非常に複雑で、平行移動/縮尺/回転の値を格納しません。座標を掛けると平行移動/縮尺/回転の値が得られるいくつかの値で構成されているため、マトリックスを反転することは期待できません。平行移動、縮尺、回転が反転した行列を取得します。

あなたはここでそれらについてもっと読むことができます。

あなたのコメントに答えるために編集してください:

行列を操作する場合、操作の順序は非常に重要です。回転してから平行移動すると、平行移動してから回転した場合とは結果が異なります。

行列に適用された操作を逆にするには、逆の順序で反対の操作を適用する必要があります。この場合、これを逆にします。

CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform, x1, x2);
CGAffineTransform transform2 = CGAffineTransformScale(transform1, r1, r2);
CGAffineTransform transform3 = CGAffineTransformRotate(transform2, a);

これを行う必要があります:

CGAffineTransform reversed3 = CGAffineTransformRotate(transform3, -a);
CGAffineTransform reversed2 = CGAffineTransformScale(reversed3, 1/r1, 1/r2);
CGAffineTransform reversed1 = CGAffineTransformTranslate(reversed2, -x1, -x2);

[view setTransform:reversed1];

以前にビューの変換を変更したことがない場合は、次のようにすることができます。

[view setTransform:CGAffineTransformIdentity];

これは、ゼロ回転、ゼロ平行移動、および1のスケールです。

于 2012-05-12T01:22:32.967 に答える
0

CGAffineTransformIdentityあなたが何をしようとしているのか理解できませんが、testAnimationメソッドでビューの変換を元に戻すだけではいけませんか?

于 2012-05-12T00:59:27.593 に答える
0

以下のコードを検討してください。ここにtransformTestがあり、その上にtransform3を適用します。次に、transform3の逆の結果の上に適用します。最終結果はtransformTestにかなり近くなります(浮動小数点の精度が低くなります)。

あなたがview.transform = CGAffineTransformConcat(view.transform, transformInverted);あなたのコードでやるなら、それはうまくいくでしょう。

CGAffineTransform transformStart = CGAffineTransformIdentity;
CGAffineTransform transform1 = CGAffineTransformTranslate(transformStart, 10, 23);
CGAffineTransform transform2 = CGAffineTransformScale(transform1, 2, 10);
CGAffineTransform transform3 = CGAffineTransformRotate(transform2, M_PI_4);

CGAffineTransform invertedTransform = CGAffineTransformInvert(transform3);


// here actual test
NSLog(@"--------------- here actual test ---------------");

CGAffineTransform transformTest = CGAffineTransformMakeTranslation(2, 15);
transformTest = CGAffineTransformRotate(transformTest, M_PI_2);
transformTest = CGAffineTransformScale(transformTest, 19, 0.4);
transformTest = CGAffineTransformTranslate(transformTest, -33, -19);
NSLog(@"transformTest %@", NSStringFromCGAffineTransform(transformTest));

CGAffineTransform transformTestMultiplied = CGAffineTransformConcat(transformTest, transform3);
NSLog(@"transformTestMultiplied %@", NSStringFromCGAffineTransform(transformTestMultiplied));

CGAffineTransform transformTestMultipliedByInverse = CGAffineTransformConcat(transformTestMultiplied, invertedTransform);
NSLog(@"transformTestMultipliedByInverse %@", NSStringFromCGAffineTransform(transformTestMultipliedByInverse));

これの出力:

2016-07-19 13:49:22.034 testUIView[45050:69431115] --------------- here actual test ---------------
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTest [1.1634144591899855e-15, 19, -0.40000000000000002, 2.4492935982947065e-17, 9.5999999999999623, -612]
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTestMultiplied [-26.870057685088803, 134.35028842544403, -0.56568542494923812, -2.8284271247461898, 889.0751503711158, -4236.611249867763]
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTestMultipliedByInverse [0, 19, -0.40000000000000002, 0, 9.5999999999999162, -612]
于 2016-07-19T20:54:10.210 に答える