2

時間に応じてさまざまなサブレイヤーでCALayerを回転させようとしています。新しいタイムコードを受信するUDPマルチキャストレシーバーが設置されています。タイマーを介して新しい時間を取得します。

 [NSTimer scheduledTimerWithTimeInterval:0.02f
 target:self
 selector:@selector(fetchNewTimeAndRotate)
 userInfo:nil
 repeats:YES];

CALayerは時間に応じてローテーションする必要があります。私の場合、1.8秒で1回転します。実際、アニメーションは必要ありません。角度を頻繁に設定するだけで、実際のアニメーションが生成されます。

さまざまな方法でレイヤーの回転を設定してみました。

最初にCATransform3DMakeRotationで試しました:

CATransform3D rotation1 = CATransform3DMakeRotation([self DegreesToRadians:newAngle], 0.0f, 0.0f, 1.0f);
self.circleLayer.transform=rotation1

2番目の試みは、アニメーションを介してインスタント回転を使用することでした。

rotation.fromValue = [NSNumber numberWithFloat:[self DegreesToRadians:oldAngle]];
rotation.toValue = [NSNumber numberWithFloat:[self DegreesToRadians:newAngle]];
rotation.duration = 0.0f;
rotation.repeatCount = 0.0f;
rotation.removedOnCompletion = NO; //also used YES here with no effect
[self.circleLayer addAnimation:rotation forKey:@"transform.rotation.z"];
oldAngle=newAngle;

3回目の試行は、角度を「transform.rotation.z」に設定することでした。

[self.circleLayer setValue:[NSNumber numberWithFloat:[self DegreesToRadians:newAngle]] forKeyPath:@"transform.rotation.z"];

上記のアプローチはすべて機能しますが、ローテーションで大きな吃音が発生します。フェッチとアニメーションの長さでいくつかの異なるタイミングを使用してみました。問題を取り除くものは何もないようです。0.02と3.6°の角度ごとに自動回転を使用することが、私にとってスムーズな結果を示した唯一のオプションです。私はここで根本的な間違いを犯していますか、それともCoreAnimationの概念を理解していませんか?アニメーション自体を作るために使われることを私は知っています。しかし、ユーザー入力に反応してすぐに変更するために必要です。助けてくれてありがとう。

4

1 に答える 1

0

CADisplayLinkのことですよね?

DisplayLink オブジェクトは、OpenGL のフレームベースのアニメーションによく使用されますが、「OpenGL を使用」しません。表示リンクを作成し、それをアプリケーションに添付して描画をトリガーすることは完全に有効です。

他のポスターが言ったように、NSTimer はアニメーション フレームの微調整には適していません。タイマーを動かして計測するだけのプログラムを書けば見栄えがします。ただし、タイマーは、アプリがイベント ループに頻繁にアクセスするかどうかに依存します。それらはプリエンプティブではなく、タイマーが起動するときにアプリがビジー状態の場合、タイマーがオフになるか、起動間隔を逃すことさえあります。

引き続き表示リンクを使用する場合は、コードを記述して、最後のフレームからの経過時間を確認し、それに基づいてアニメーション化する量を計算することをお勧めします。そうすれば、フレームをドロップしてもアニメーションは正しい速度で進行します (フレームをドロップすると、次のフレームまでに 2 倍の時間がかかるため、オブジェクトを 2 倍に動かします)。

于 2012-12-04T01:56:33.240 に答える