2016-07-25 3 views
8

Я пытаюсь сделать пользовательский индикатор активности, подобный индикатору активности, показывающему круговую неопределенность активности Android. В принципе, я хочу нарисовать круг два раза и стереть его, но стирание и рисование не происходит одновременно или быстро. Это то, что у меня есть до сих пор:Подключитесь к анимации двухтактных анимаций

let progressLayer = CAShapeLayer() 
progressLayer.strokeColor = UIColor.red().cgColor 
progressLayer.fillColor = nil 
progressLayer.lineWidth = 2 

let drawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
drawAnimation.duration = duration/2 
drawAnimation.fromValue = 0 
drawAnimation.toValue = 1 
drawAnimation.isRemovedOnCompletion = false 
drawAnimation.fillMode = kCAFillModeForwards 

let eraseAnimation = CABasicAnimation(keyPath: "strokeStart") 
eraseAnimation.duration = duration/2 
eraseAnimation.beginTime = 0.2 
eraseAnimation.fromValue = 0 
eraseAnimation.toValue = 0.4 
eraseAnimation.isRemovedOnCompletion = false 
eraseAnimation.fillMode = kCAFillModeForwards 

let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
endDrawAnimation.beginTime = duration/2 
endDrawAnimation.duration = duration/2 
endDrawAnimation.fromValue = 0 
endDrawAnimation.toValue = 1 
endDrawAnimation.isRemovedOnCompletion = false 
endDrawAnimation.fillMode = kCAFillModeForwards 

let endEraseAnimation = CABasicAnimation(keyPath: "strokeStart") 
endEraseAnimation.beginTime = duration/2 
endEraseAnimation.duration = duration/4 
endEraseAnimation.fromValue = 0.4 
endEraseAnimation.toValue = 1 
endEraseAnimation.isRemovedOnCompletion = false 
endEraseAnimation.fillMode = kCAFillModeForwards 

let endEraseAnimation2 = CABasicAnimation(keyPath: "strokeStart") 
endEraseAnimation2.beginTime = duration * 3/4 
endEraseAnimation2.duration = duration/4 
endEraseAnimation2.fromValue = 0 
endEraseAnimation2.toValue = 1 
endEraseAnimation2.isRemovedOnCompletion = false 
endEraseAnimation2.fillMode = kCAFillModeForwards 


let animations = CAAnimationGroup() 
animations.duration = duration 
animations.animations = [drawAnimation, eraseAnimation, endDrawAnimation, endEraseAnimation, endEraseAnimation2] 
animations.isRemovedOnCompletion = false 
animations.fillMode = kCAFillModeForwards 
progressLayer.add(animations, forKey: "stroke") 

Код делает все, как ожидалось, за исключением одной проблемы. Когда первая анимация strokeEnd начинается, а вторая начинается, есть какая-то вспышка, означающая часть круга, которая была нарисована до тех пор, пока эта точка не исчезнет, ​​а затем рисунок снова начнется с 0. Есть ли у кого-нибудь идеи, как это исправить?

+0

Ваши показать ошибки код, когда я пытаюсь скомпилировать, пожалуйста, поместите ваш реальный код, для того, чтобы помочь вы –

+0

@ReinierMelian это код Swift 3, убедитесь, что вы используете Xcode 8 или переводите его в Swift 2. @Banana, что такое 'progressLayer'? – JAL

+0

'progressLayer' является' CAShapeLayer', я добавил это к вопросу выше. – Banana

ответ

0

Когда первый strokeEnd анимация сделана и вторая одна начинает там вроде вспышки, означающей часть круга, было нарисована до этого момента исчезает, а затем рисунок начинается снова с 0.

Если вы сравните настройку drawAnimation и endDrawAnimation, вы увидите, что они идентичны, за исключением beginTime. Вот почему вы мерцаете. Они оба начинаются с 0, и они оба конца с 1. Так как вы не указали желаемый результат, я могу только предположить, что вы хотите endDrawAnimation иметь fromValue из 1.

let drawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
drawAnimation.duration = duration/2 
drawAnimation.fromValue = 0 
drawAnimation.toValue = 1 
drawAnimation.isRemovedOnCompletion = false 
drawAnimation.fillMode = kCAFillModeForwards 

let endDrawAnimation = CABasicAnimation(keyPath: "strokeEnd") 
endDrawAnimation.beginTime = duration/2 // Starts after the first animation and starts with 0 again. 
endDrawAnimation.duration = duration/2 
endDrawAnimation.fromValue = 0 
endDrawAnimation.toValue = 1 
endDrawAnimation.isRemovedOnCompletion = false 
endDrawAnimation.fillMode = kCAFillModeForwards 

предложения по улучшению

Насколько я вижу, вы хотите создать анимацию ключевого кадра, что означает, что у вас есть предопределенные смещения, при которых изменяется поведение анимации (скорость, значение и т. Д.). Возможно, вы захотите использовать вместо этого CAKeyframeAnimation.

Я уверен, если вы знаете об этом, но в данный момент у вас есть две анимации, работающих одновременно на strokeStart:

  • eraseAnimation, который начинается в 0.2 с длительностью 0.5 * duration
  • endEraseAnimation, который начинается в 0.5 * duration ,

Это означает, что конец eraseAnimation (0.2 + 0.5 * duration) всегда больше, чем в начале endEraseAnimation (0.5 * duration)

Смежные вопросы