設定された進行状況に基づいて 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
前回の更新以降に縮小した場合です。私が経験している問題は、実際にはいくつかあります。
- 形状は常に45 度から描画を開始します (ビューを回転させない限り)。これを変更する方法が見つかりません
startAngle
でした。-45º に設定しても、常に 45 に「ポップ」されるため、実際には違いはありません。 - これらのものをアニメーション化する他の方法はありますか? 私は使用について多くのことを読みました
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)];
そして今、すべてが正常に機能します。助けてくれてありがとう!