У меня есть приложение, которое анимирует маленькое красное подпредставление, используя добавленную анимацию.Первая анимация сдвигает вид вниз на 100 пунктов.Вторая анимация включается на полпути и перемещает вид на 100 пунктов вправо.Анимации вниз и вправо являются аддитивными, что приводит к диагональному движению в нижнем правом углу.Кроме того, обе анимации автоматически реверсируются, поэтому представление восстанавливается в исходное положение поверх небольшого зеленого подпредставления «маркер».
Из приведенного выше рисунка видно, что анимация представления ведет себя как ожидалось до тех пор, пока не завершится автореверс, после чего представление переместится влево (очевидно, на 100 пунктов).Обычно такой скачок будет результатом отсутствия установки состояния представления в соответствии с последним кадром анимации.Однако состояние представления действительно правильно (?) Устанавливается методом завершения аниматора - это подтверждается информацией, предоставленной операторами print.
Что является причиной окончательного просмотра слевапрыжок?
См. соответствующий код ниже.Полный проект может быть загружен с GitHub
У меня есть догадка, что вызовы UIView.setAnimationRepeatAutoreverses в каждом из двух закрытий анимации могут быть виновником.Мне не ясно, что то, что я сделал в этом отношении, согласуется с ожиданиями структуры.
class ViewController: UIViewController {
private var markerView: UIView!
private var animationView: UIView!
override func viewDidLoad() {
view.backgroundColor = .black
view.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(tapGestureHandler)))
let frame = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 10, height: 10)
markerView = UIView(frame: frame)
markerView.backgroundColor = .green
view.addSubview(markerView)
animationView = UIView(frame: frame)
animationView.backgroundColor = .red
view.addSubview(animationView)
}
@objc private func tapGestureHandler(_ sender: UITapGestureRecognizer) {
animate()
}
// Move down; half way through begin moving right while still moving down.
// Autoreverse it.
private func animate() {
let distance: CGFloat = 100
let down = {
UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.y += distance
}
let right = {
UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.x += distance
}
print("\nCenter: \(self.animationView.center)")
let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: down)
animator.addAnimations(right, delayFactor: 0.5)
animator.addCompletion { _ in
print("Center: \(self.animationView.center)")
self.animationView.center.x -= distance
self.animationView.center.y -= distance
print("Center: \(self.animationView.center)")
}
animator.startAnimation()
}
}
Обновление 1
Я добавил два другихверсии метода одушевления, которые являются информативными.Основываясь на том, что я узнал из этих двух версий, я изменил название этого вопроса.
animate2: вызовы UIView.setAnimationRepeatAutoreverses были закомментированы в каждой из нижних и правых функций анимации.Этот модифицированный код функционирует как ожидалось.Конечно, мы не получаем плавный автореверсивный эффект.
extension ViewController {
private func animate2() {
let distance: CGFloat = 100
let down = {
//UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.y += distance
}
let right = {
//UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.x += distance
}
print("\nCenter: \(self.animationView.center)")
let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: down)
animator.addAnimations(right, delayFactor: 0.5)
animator.addCompletion { _ in
print("Center: \(self.animationView.center)")
self.animationView.center.x -= distance
self.animationView.center.y -= distance
print("Center: \(self.animationView.center)")
}
animator.startAnimation()
}
}
animate3: добавлено добавление второй (то есть правой) анимации,Этот модифицированный код функционирует как ожидалось.Конечно, мы не получаем движение вправо.
extension ViewController {
private func animate3() {
let distance: CGFloat = 100
let down = {
UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.y += distance
}
let right = {
UIView.setAnimationRepeatAutoreverses(true)
self.animationView.center.x += distance
}
print("\nCenter: \(self.animationView.center)")
let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: down)
//animator.addAnimations(right, delayFactor: 0.5)
animator.addCompletion { _ in
print("Center: \(self.animationView.center)")
self.animationView.center.y -= distance
//self.animationView.center.x -= distance
print("Center: \(self.animationView.center)")
}
animator.startAnimation()
}
}
Похоже, что вызов UIView.setAnimationRepeatAutoreverses в обеих функциях анимации"испортить вещи".Мне не ясно, можно ли это по праву считать ошибкой iOS.