ios - 遅れる - 操作をアニメーションで表示する



円形のUIBezierPathをアニメーション化する (1)

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

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

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

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 startAngleに設定することは、常に45に "ポップ"するので、違いはありません。これについて何かできるか、あるいは他の描画方法に頼らなければならないか?
  2. これらのことを動かすべき他の方法はありますか? 私はCAShapeLayerについて多くのことをCAShapeLayerだことがありますが、これらの2つの方法を使用する際の実際の違い(欠点とメリットの点で)はあまり理解していません。 誰かが明確にできるならば、私は非常に義務づけられます!

更新:代わりにコードをCAShapeLayerに移行しましたが、今は別の問題に直面しています。 これは、この画像で最もよく説明されています:

起こっていることは、レイヤーが縮小すると思われるときに、細い外線が(移動方向に関係なく)そこにあることです。 バーが縮小すると、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"];

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

何か案は?

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

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

そして今はすべてがうまくいくはずです。 すべての助けをありがとう!





cadisplaylink