У меня есть проект, в котором я анимация UIBezierPath на основе достигнутого прогресса. BezierPath находится в форме круга и находится в UIView, и анимация выполняется в drawRect с помощью CADisplayLink прямо сейчас. Проще говоря, на основе достигнутого прогресса 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
, но я не совсем понял фактическую разницу (с точки зрения недостатков и преимуществ) при использовании этих двух методов. Если бы кто-нибудь мог прояснить, я был бы очень обязан!
UPDATE: Я перевел код на 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)];
И теперь все работает так, как должно. Спасибо за помощь!