3

レイヤーの変換のスケールと変換を同時に実行したいのですが、変換アニメーションのみが実行されます。これが誤ったコードです...

ここでは、scale.yへのキーパスを使用してスケールアニメーションを作成します。

    self.mainImage.layer.anchorPoint = CGPointMake(0.5, 1);
    CAKeyframeAnimation *mainAnimationScale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.y"];
    mainAnimationScale.duration             = 0.75;
    mainAnimationScale.repeatCount          = 0;
    mainAnimationScale.removedOnCompletion  = YES;
    mainAnimationScale.autoreverses         = NO;
    mainAnimationScale.fillMode             = kCAFillModeForwards;
    mainAnimationScale.values               = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:0.7],
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:0.85],
                                          [NSNumber numberWithFloat:1.0],
                                           nil];
    mainAnimationScale.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:0.72],
                                          [NSNumber numberWithFloat:0.84],
                                          [NSNumber numberWithFloat:0.91],
                                          [NSNumber numberWithFloat:1],
                                           nil];

ここでは、translation.yへのキーパスを使用して翻訳アニメーションを作成します。

    CAKeyframeAnimation *mainAnimationTrans = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    mainAnimationTrans.duration             = 0.75;
    mainAnimationTrans.repeatCount          = 0;
    mainAnimationTrans.removedOnCompletion  = YES;
    mainAnimationTrans.autoreverses         = NO;
    mainAnimationTrans.fillMode             = kCAFillModeForwards;
    mainAnimationTrans.values               = [NSArray arrayWithObjects:
                                         [NSNumber numberWithFloat:-250.0],
                                         [NSNumber numberWithFloat:-250.0],
                                         [NSNumber numberWithFloat:0],
                                           nil];
    mainAnimationTrans.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:1],
                                           nil];

ここで、それらをグループ化し、UIViewのレイヤーに適用します。

    CAAnimationGroup *theGroup = [CAAnimationGroup animation];
    theGroup.duration = 0.75;
    theGroup.repeatCount = 0;
    theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    theGroup.animations = [NSArray arrayWithObjects:mainAnimationTrans, mainAnimationScale, nil];
    [self.mainImage.layer addAnimation:theGroup forKey:@"layerAnimation"];

最初は、このようにアニメーションをレイヤーに直接追加しようとしましたが、それも機能しませんでした。

    [self.mainImage.layer addAnimation:mainAnimationTrans forKey:@"transform.scale.y"];
    [self.mainImage.layer addAnimation:mainAnimationTrans forKey:@"transform.translation.y"];

keyPath値について考えられるすべての文字列を試しましたが、変換の2つの側面をアニメーション化しているという事実と関係があると思いますが、グループを使用するとそれが修正されると思いました。ああ...

4

2 に答える 2

2

この作業を行うための鍵は、変換を組み合わせることです。基本的な行列の数学なので、なぜ早く気づかなかったのかわかりません...昨日も同僚が言っていたと思います。確認します。

とにかく、私が目指していたアニメーションは、アイテムが目的地に到達したら、アイテムをドロップダウンしてバウンスさせることでした。コードは次のとおりです。

    self.mainImage.layer.anchorPoint = CGPointMake(0.3, 1.0);
    CAKeyframeAnimation *mainImageAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    mainImageAnimation.duration             = 0.75;
    mainImageAnimation.repeatCount          = 0;
    mainImageAnimation.removedOnCompletion  = NO;
    mainImageAnimation.autoreverses         = NO;
    mainImageAnimation.fillMode             = kCAFillModeForwards;
    mainImageAnimation.values               = [NSArray arrayWithObjects:
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, -250, 0), 1, 1, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1, 1, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1.2, .8, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), .85, 1.15, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1.1, .9, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1, 1, 1)],
                                           nil];
    mainImageAnimation.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.6],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:0.78],
                                          [NSNumber numberWithFloat:0.88],
                                          [NSNumber numberWithFloat:1],
                                           nil];
    mainImageAnimation.timingFunctions      = [NSArray arrayWithObjects:
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                           nil];
    [self.mainImage.layer addAnimation:mainImageAnimation forKey:@"transform"];

注意事項:

  • 複数の変換プロパティを有効にするには、CATransform3DMakeXXX関数の結果をCATransform3DXXX関数の変換引数にフィードすることにより、個々の変換を結合ます。
  • Matrix mathでは、変換の順序が重要です。マトリックスに最後にフィードするものが、最初に適用されるものになります。私の場合、縮尺の前に平行移動を適用したいので、最初に縮尺変換を作成して、それを後続の変換変換に適用する必要があります。
  • レイヤーのanchorPointを変更すると、レイヤーの位置が変更されます。私の場合、ancorポイントを非対称にする必要があり、平行移動変換での位置の変化をどのように説明するかがわかります。静止場所は0,0ではなく-8,17です。

お役に立てれば!

于 2012-05-25T15:04:44.733 に答える
0

質問とは異なりますが、関連して、回転とスケールの2つのCAKeyFrameAnimationsを組み合わせようとしました。

CAKeyframeAnimation *wiggle = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
wiggle.values   = @[ @0.0, @-0.15, @0.0, @0.15, @-0.15, @0.0];
wiggle.keyTimes = @[ @0.0, @0.2,  @0.4, @0.6, @0.8,  @1.0];
wiggle.duration = 0.5;

CAKeyframeAnimation *resize = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
resize.duration = 0.5;
resize.values = @[@1.0, @1.5, @1.0];
resize.keyTimes = @[@0.0, @0.5, @1.0];

回転のみが発生していたため、アニメーションを個別に追加することはできませんでした。

[self.layer addAnimation:wiggle forKey:kAnimationKey];
[self.layer addAnimation:resize forKey:kAnimationKey];

しかし、両方のCAKeyFrameAnimationsを含むアニメーショングループを作成したときに機能しました。

CAAnimationGroup *animGroup = [[CAAnimationGroup alloc] init];
animGroup.animations = @[wiggle, resize];
animGroup.duration = 0.5;

[self.layer addAnimation:animGroup forKey:kAnimationKey];
于 2014-05-12T18:35:24.510 に答える