Анимация UIView возвращается к исходному состоянию, прежде чем перейти к новому виду - PullRequest
1 голос
/ 03 октября 2019

У меня есть несколько UIB-кнопок, которые я анимирую бесконечно. Все кнопки имеют 3 добавленных подслоя, каждый из которых имеет свою собственную анимацию. Я инициализирую эти анимации на viewDidAppear, что прекрасно работает - они исчезают и начинают вращаться. Проблема заключается в том, что при переходе к новому представлению анимации, похоже, «возвращаются» в исходное состояние, а затем обратно в какое-то другое состояние непосредственно перед тем, как происходит переход. Я пытался явно удалить все анимации в viewWillDisappear, даже пытался скрыть весь UIButton, но, похоже, ничто не мешает этому странному поведению привязки.

Вот гиф того, что происходит (это я перехожуназад и вперед между двумя представлениями):

enter image description here

func animateRotation() {
// Gets called on viewDidAppear

    let rotationRight: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    rotationRight.toValue = Double.pi * 2
    rotationRight.duration = 4
    rotationRight.isCumulative = true
    rotationRight.repeatCount = Float.greatestFiniteMagnitude
    rotationRight.isRemovedOnCompletion = false
    rotationRight.fillMode = .forwards

    let rotationLeft: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    rotationLeft.toValue = Double.pi * -2
    rotationLeft.duration = 3
    rotationLeft.isCumulative = true
    rotationLeft.repeatCount = Float.greatestFiniteMagnitude
    rotationLeft.isRemovedOnCompletion = false
    rotationLeft.fillMode = .forwards

    let circleImage1 = UIImage(named: "circle_1")?.cgImage
    circleLayer1.frame = self.bounds
    circleLayer1.contents = circleImage1
    circleLayer1.add(rotationRight, forKey: "rotationAnimation")
    layer.addSublayer(circleLayer1)

    let circleImage2 = UIImage(named: "circle_2")?.cgImage
    circleLayer2.frame = self.bounds
    circleLayer2.contents = circleImage2
    circleLayer2.add(rotationLeft, forKey: "rotationAnimation")
    layer.addSublayer(circleLayer2)

    let circleImage3 = UIImage(named: "circle_3")?.cgImage
    circleLayer3.frame = self.bounds
    circleLayer3.contents = circleImage3
    circleLayer3.add(rotationRight, forKey: "rotationAnimation")
    layer.addSublayer(circleLayer3)
}

Я думаю, что-то настолько простое, что это полностью скрыло бы кнопку, как только она узнаетон уходит:

override func viewWillDisappear(_ animated: Bool) {
    animatedButton.isHidden = true
}

Интересно также то, что, кажется, это перестает происходить, если я позволю ему работать в течение пары минут. Это говорит мне, что это может быть какое-то состояние гонки. Просто не уверен, что это может быть за раса ...

1 Ответ

1 голос
/ 03 октября 2019

Когда вы используете набор анимаций UIView, они устанавливают фактическое состояние в конечное состояние и затем запускают анимацию, то есть:

UIView.animate(withDuration: 1) { view.alpha = 0 }

Если вы проверяете альфа сразу после запуска анимации, она уже равна 0.

Это удобство, которое UIView делает для вас, а CALayer - нет. Когда вы устанавливаете анимацию CALayer, вы устанавливаете только значение анимации, а не фактическое значение переменной, поэтому, когда анимация завершена, слой возвращается к своему первоначальному значению. Проверьте значение слоя, пока вы находитесь в середине анимации, и вы увидите, что реальное значение не изменилось;изменилось только анимированное значение в уровне представления.

Если вы хотите повторить поведение UIView, вам нужно либо установить фактическое конечное значение, а не слой, когда анимация начинается, или использовать делегат для его установки. когда анимация заканчивается.

...