2013-11-21 16 views
17

私は、設定された進捗状況に基づいてUIBezierPathをアニメートするプロジェクトを持っています。 BezierPathは円の形をしており、UIViewにあり、現在CADisplayLinkを使用してdrawRectでアニメーションが行われています。簡単に言えば、設定進捗状況に基づいて、xパスは半径方向に拡張するか(xが以前より大きい場合)、または縮小する(xが小さい場合)。円形のアニメーションUIBezierPath

self.drawProgress = (self.displayLink.timestamp - self.startTime)/DURATION; 

CGFloat startAngle = -(float)M_PI_2; 
CGFloat stopAngle = ((self.x * 2*(float)M_PI) + startAngle); 
CGFloat currentEndAngle = ((self.oldX * 2*(float)M_PI) + startAngle); 
CGFloat endAngle = currentEndAngle-((currentEndAngle-stopAngle)*drawProgress); 

UIBezierPath *guideCirclePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; 

これは、最後の更新以来、xの場合に縮小しています。

  1. 形状45°で描く常に開始(私はビューを回転させない限り):私は経験してるの問題は、実際にいくつかあります。私はこれを変更する方法を見つけていないし、startAngleを-45ºに設定すると、実際には45に "ポップ"するので、違いはありません。これについて何かできるか、または他の描画方法?
  2. これらをアニメーション化する方法は他にありますか?私はCAShapeLayerを使用して多くのことを読んだことがありますが、これらの2つの方法を使用する際の実際の違い(欠点とメリットの点で)はあまり理解していません。誰かが明確にできるならば、私は非常に義務づけられます!

UPDATE:私が代わりにCAShapeLayerに上のコードを移行し、今、私は別の問題に直面しています。それは最高のこのイメージを説明しています:何が起こっている

enter image description here

は層が縮小することになっているとき、薄い外側のラインが(関係なく、運動の方向の)まだそこにあるということです。また、バーが縮小すると、デルタ1 - xは明示的に新しい白いシェイプを作成しない限り削除されません。このコードは次のとおりです。何か案は?

UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:stopAngle clockwise:YES]; 
CAShapeLayer *circle = [CAShapeLayer layer]; 
circle.path = [circlePath CGPath]; 
circle.strokeStart = 0; 
circle.strokeEnd = 1.0*self.progress; 

// Colour and other customizations here. 

if (self.progress > self.oldProgress) { 
    drawAnimation.fromValue = @(1.0*self.oldProgress); 
    drawAnimation.toValue = @(circle.strokeEnd); 
} else { 
    drawAnimation.fromValue = @(1.0*self.oldProgress); 
    drawAnimation.toValue = @(1.0*self.progress); 
    circle.strokeEnd = 1.0*self.progress; 
} 

drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //kCAMediaTimingFunctionEaseIn 
[circle addAnimation:drawAnimation forKey:@"strokeEnd"]; 

UPDATE 2:私は他のバグのほとんどをアイロンをかけてきました。それは、私が全体のアニメーション全体をむしろばかげているだけであったことが判明しました(どこでも1倍になるのはもちろんですが)。

radial control glitch

任意のアイデア:私は解決できないバグのGIFを作りましたか?

更新3:(およびクロージャ)。私は電話でバグを取り除くことができました

[self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; 

そして今はすべてが正常に動作します。すべての助けをありがとう!

+0

[これ(セグメントの角度を0〜360度に拡大して円を描きます)](http://stackoverflow.com/a/8021051/608157)と同様の操作を行いますか? –

+0

私はCAShapeLayer + CABasicAnimationを使用して移行しました。なぜなら、ダンカンが推奨するプロパティを使用できるという理由から、より多くの選択肢があるように思われるからです。 – hav

+0

スウィフトで良い解決策を探しています。 – hugocarlmartin

答えて

10

CAShapeLayerの使用はずっと簡単でクリーンです。理由は、CAShapeLayerには、プロパティstrokeStartとstrokeEndが含まれているからです。これらの値の範囲は0(パスの先頭)から1(パスの最後)までで、アニメーション化可能です。

円を変更することで、サークルの任意の弧(または任意のパスの任意の部分)を簡単に描画できます。プロパティはアニメーション可能なので、拡大/縮小しているパイスライスまたはセクションのアニメーションを作成できますリング形状のものである。 drawRectにコードを実装するよりもはるかに簡単でパフォーマンスが向上します。

+1

これは事実を単純化し、私はコードをCAShapeLayerとCABasicAnimationに基づいたソリューションを使用するように移行しました。しかし、今、私は違う奇妙なことを経験しています... – hav

+1

そして、それはどういう奇妙なものですか? –

関連する問題