1

UIView アニメーションについての回答を投稿しないでください。UIView を理解しています。コア アニメーションを学んでいます。右に 50 単位移動するイメージを取得しようとしていますが、多くの問題があります。最初にアニメーションが呼び出されると、画像は新しい場所にジャンプして実行され、次に元の場所に戻ります。ボタンが押されたら、50単位右に移動し、停止し、再び移動するだけです。調査に多くの時間を費やしましたが、問題が見つからないようです。私のコード:

-(IBAction)preform:(id)sender{

CGPoint point = CGPointMake(imView.frame.origin.x, imView.frame.origin.y);
imView.layer.position = point;

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
anim.fromValue  = [NSValue valueWithCGPoint:point];
anim.toValue    = [NSValue valueWithCGPoint:CGPointMake(point.x + 50, point.y)];
anim.duration   = 1.5f;
anim.repeatCount =1;
anim.removedOnCompletion = YES;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[imView.layer  addAnimation:anim forKey:@"position.x"];
imView.layer.position = point;

}
4

3 に答える 3

16

あなたのコードにはいくつかの問題があります。

まず、次のようにフレームの原点を取得します。

CGPoint point = CGPointMake(imView.frame.origin.x, imView.frame.origin.y);

それは実際には問題ではありませんが、単純にこれを行うことができます:

CGPoint point = imView.frame.origin;

問題は、レイヤーpositionをフレームの原点に設定していることです。ただし、デフォルトでは、位置はビューの中心を制御し、フレームの原点は左上隅です。おそらく、最初にレイヤーの位置を取得したいでしょう:

CGPoint point = imView.layer.position; // equivalent to imView.center

次に、値が必要position.xなキー パスを使用してCGFloatいますが、値を提供していCGPointます。これが iOS 6.1 シミュレーターで問題を引き起こすようには見えませんが、常に動作すると仮定するのはおそらく悪い考えです。

第三に、アニメーションはレイヤーのプロパティを変更しないことを理解する必要があります! 通常操作する各レイヤー (技術的にはモデルレイヤーと呼ばれます) には、関連付けられたプレゼンテーションレイヤーがあります。プレゼンテーション レイヤーのプロパティは、画面に表示される内容を制御します。モデル レイヤーのプロパティを変更すると、Core Animation は通常、プレゼンテーション レイヤーに (古い値から新しい値への) アニメーションを自動的に設定します。これは暗黙のアニメーションと呼ばれます。AUIViewは、レイヤー上で暗黙的なアニメーションを抑制します。

プレゼンテーション レイヤーのアニメーションが終了して削除されると、プレゼンテーション レイヤーのプロパティはモデル レイヤーの値に戻ります。したがって、変更を永続的にするには、モデル レイヤーのプロパティを更新する必要があります。一般的には、最初にモデル レイヤーのプロパティを更新してからアニメーションを追加し、明示的なアニメーションが暗黙的なアニメーション (作成されている場合) を上書きすることをお勧めします。

たまたま、アニメートすることはできますが、貼り付けるにはレイヤーにposition.x設定する必要があります。私はこれが動作することをテストしました:positionmodel

- (IBAction)perform:(id)sender {
    CGPoint point0 = imView.layer.position;
    CGPoint point1 = { point0.x + 50, point0.y };

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
    anim.fromValue    = @(point0.x);
    anim.toValue  = @(point1.x);
    anim.duration   = 1.5f;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    // First we update the model layer's property.
    imView.layer.position = point1;

    // Now we attach the animation.
    [imView.layer  addAnimation:anim forKey:@"position.x"];
}

(私が my method と呼んだことに注意してくださいperform:。元の投稿のメソッドのスペルが間違っているようです。)

Core Animation を本当に理解したい場合は、WWDC 2011 のCore Animation Essentials ビデオを見ることを強くお勧めします。これは 1 時間の長さで、有益な情報がたくさん含まれています。

于 2013-02-12T00:04:03.340 に答える
1

これは、それを機能させるために必要なものです。レイヤー上の位置は既に設定されているので、それを として使用し、fromValueそれを変更して を取得できますtoValue。もう 1 つの重要なステップは、レイヤーの位置を に設定してendPos、アニメーションが終了したときにイメージ ビューが正しい位置にとどまるようにすることです。

-(IBAction)preform:(id)sender
{
    CGPoint startPos = imView.layer.position;
    CGPoint endPos = CGPointMake(point.x + 50, point.y);

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
    anim.fromValue  = [NSValue valueWithCGPoint:startPos];
    anim.toValue    = [NSValue valueWithCGPoint:endPos];
    anim.duration   = 1.5f;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    [imView.layer addAnimation:anim forKey:@"position.x"];
    imView.layer.position = endPos;
}
于 2013-02-12T00:01:50.773 に答える
-1

ジャンプバックは、完了時にアニメーションを削除することが原因です

anim.removeOnCompletion = NO;

編集#3:ここにコードをコピーして試してみましたが、すべての問題の修正であり、ほとんど自明です:

CGPoint point = imView.center;
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
anim.fromValue  = [NSNumber numberWithFloat:point.x];
anim.toValue    = [NSNumber numberWithFloat:point.x+50.0];//[NSValue valueWithCGPoint:CGPointMake(point.x + 50, point.y)];
anim.duration   = 1.5f;
anim.repeatCount =1;
anim.removedOnCompletion = NO;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
anim.fillMode=kCAFillModeForwards;
[imView.layer  addAnimation:anim forKey:@"position.x"];
[sender.layer  addAnimation:anim forKey:@"position.x"];
sender.layer.position=CGPointMake(point.x+50.0,sender.layer.position.y);

removedOnCompletion が no に設定されているにもかかわらず、ジャンプして戻るという事実は頭を悩ませます。まだそれで遊んでいます。

于 2013-02-11T23:45:52.357 に答える