UIViewPropertyAnimator не учитывает параметры длительности и задержки - PullRequest
0 голосов
/ 03 мая 2020

У меня очень странная проблема в моем приложении. Я использую UIViewPropertyAnimator для анимации изменяющихся изображений внутри UIImageView.

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

Вот код:

private lazy var images: [UIImage?] = [
    UIImage(named: "widgethint"),
    UIImage(named: "shortcuthint"),
    UIImage(named: "spotlighthint")
]
private var imageIndex = 0
private var animator: UIViewPropertyAnimator?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    animator = repeatingAnimator()
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    animator?.stopAnimation(true)
}

private func repeatingAnimator() -> UIViewPropertyAnimator {
    return .runningPropertyAnimator(withDuration: 2, delay: 6, options: [], animations: {
        self.imageView.image = self.images[self.imageIndex]
    }, completion: { pos in
        if self.imageIndex >= self.images.count - 1 {
            self.imageIndex = 0
        } else {
            self.imageIndex += 1
        }
        self.animator = self.repeatingAnimator()
    })
}

Итак, согласно коду, анимация должна занять 2 секунды и начать с 6-секундной задержкой, но она запускается немедленно и занимает миллисекунды, поэтому я в конечном итоге с ужасным слайд-шоу. Почему это могло произойти?

Я также пытался использовать UIViewPropertyAnimator(duration: 2, curve: .linear) и вызывать repeatingAnimator().startAnimation(afterDelay: 6), но результат тот же.

1 Ответ

0 голосов
/ 03 мая 2020

Хорошо, я понял это, но все еще немного раздражает, что такая простая задача не может быть выполнена с помощью "Современного" API анимации.

Итак, анимация изображений внутри UIImageView, по-видимому, не поддерживается UIViewPropertyAnimator, во время отладки я пробовал анимировать цвет фона представления, и он работал как ожидалось. Поэтому мне пришлось использовать Timer вместо старого UIView.transition(with:) метода

Вот рабочий код:

private let animationDelay: TimeInterval = 2.4

private var animationTimer: Timer!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    setAnimation(true)
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    setAnimation(false)
}

private func setAnimation(_ enabled: Bool) {
    guard enabled else {
        animationTimer?.invalidate()
        animationTimer = nil
        return
    }
    animationTimer = Timer.scheduledTimer(withTimeInterval: animationDelay, repeats: true) { _ in
        UIView.transition(with: self.imageView, duration: 0.5, options: [.curveLinear, .transitionCrossDissolve], animations: {
            self.imageView.image = self.images[self.imageIndex]
        }, completion: { succ in
            guard succ else {
                return
            }
            if self.imageIndex >= self.images.count - 1 {
                self.imageIndex = 0
            } else {
                self.imageIndex += 1
            }
        })
    }
}

Надеюсь, в будущем это избавит кого-то от головной боли

...