2010-11-25 14 views
12

私は画面の周りを動く2つの円を持っています。サークルは両方とも他のUIViewを含むUIViewです。各円の外側の領域は透明です。コアアニメーションアニメーションを追跡する

私は、2つの円を四辺形で結ぶCGPathを作成する関数を作成しました。私は画面全体に広がる透明なCALayerでこのパスを埋める。レイヤーは2つの循環UIViewの後ろにあるため、それらを接続するように見えます。

最後に、2つのUIViewはCore Animationを使用してアニメートされます。このアニメーションでは、の位置とサイズの両方の円のが変更されます。これまでのところ

私が持つ任意の成功を収めている唯一の方法は、円のプレゼンテーション層の位置に基づいてビームを再計算して描画し、その後、NSTimerを使用して定期的にアニメーションを中断することです。ただし、四角形のは、アニメーションがスピードアップすると円の後ろにより遅れます。

コアアニメーションを使用してこれを行うより良い方法はありますか?あるいは、Core Animationを避け、NSTimerを使って自分のアニメーションを実装する必要がありますか?

答えて

12

私は同様の問題に直面しました。アニメーションのビューの代わりにレイヤーを使用しました。あなたはこのようなものを試すことができます。

  1. 各要素をCALayerとして描画し、それらをコンテナUIVIewのレイヤーのサブレイヤとして含めます。 UIViewは簡単にアニメートできますが、コントロールが少なくなります。いずれのビューでも[レイヤーを表示]でレイヤーを取得できます。
  2. 四角形のカスタムサブレイヤを作成します。このレイヤーには、このレイヤーに対してアニメートするプロパティまたはいくつかのプロパティが必要です。このプロパティを "customprop"としましょう。これはカスタムレイヤーなので、アニメーションの各フレームに再描画する必要があります。アニメートする予定のプロパティの場合、カスタムレイヤークラスはYES needsDisplayForKey:を返す必要があります。あなたが保証する方法- (void)drawInContext:(CGContextRef)theContextはすべてのフレームで呼び出されます。
  3. すべてのアニメーション(円と四角形の両方)を同じトランザクションに配置します。クワッド層のために、今すぐ

    layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage; 
    

    、サブクラスのCALayerと実装:あなたはおそらくCALayersを使用して、それが画像であれば、標準的な方法を、コンテンツを設定することができ、円の場合


この方法:

- (void)drawInContext:(CGContextRef)theContext{ 
    //Custom draw code here 
} 
+ (BOOL)needsDisplayForKey:(NSString *)key{ 
    if ([key isEqualToString:@"customprop"]) 
     return YES; 
    return [super needsDisplayForKey:key]; 
} 

トランザクションは次のようになります。

[CATransaction begin]; 
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"customprop"]; 

theAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1000, 1000)]; 
theAnimation.duration=1.0; 
theAnimation.repeatCount=4; 
theAnimation.autoreverses=YES; 
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
theAnimation.delegate = self; 
[lay addAnimation:theAnimation forKey:@"selecting"]; 

[CATransaction setValue:[NSNumber numberWithFloat:10.0f] 
        forKey:kCATransactionAnimationDuration]; 
circ1.position=CGPointMake(1000, 1000); 
circ2.position=CGPointMake(1000, 1000); 
[CATransaction commit]; 

すべての描画ルーチンは同時に実行されます。 drawInContext:実装が高速であることを確認してください。さもなければ、アニメーションは遅れます。

各サブレイヤをUIViewのレイヤに追加した後、[レイヤsetNeedsDisplay]を呼び出すように覚えておいてください。自動的に呼び出されることはありません。

私はこれが少し複雑であることを知っています。ただし、NSTimerを使用して各呼び出しで再描画するよりも、結果として得られるアニメーションが優れています。

+0

カスタムプロパティを使用する代わりに、完全にプログラム的なアニメーションを実装することを選択した方には注意してください。これには 'NSTimer'を使用しないでください。それは遅くCPUが貪欲になるでしょう。アニメーション関連のものについては、画面リフレッシュレートと同期し、CoreAnimationによって内部的に使用される['CADisplayLink'](https://developer.apple.com/library/ios/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/)を使用してください。 – skozin

1

レイヤの現在の可視状態を確認する必要がある場合は、問題のCALayerで-presentationLayerを呼び出すことができます。これにより、レンダリングに使用されたレイヤに近いレイヤが表示されます。私は近似を述べました - 完全に正確であることは保証されていません。しかしそれはあなたの目的のために十分かもしれません。

+0

私が言及したように、私はすでにpresentationLayerを使用しようとしましたが、それは円の背後にあります。私は、複数のコンポーネントのアニメーションを同期させるより信頼性の高い方法が必要です。 – titaniumdecoy

+0

私が考えることができる唯一の信頼できる方法は、アニメーション機械に結びつけることです。 CAShapeLayerを使用して、円と同期してそのパスをアニメーション化することができます。 –

関連する問題