Анимация пользовательского интерфейса с использованием animateKeyframes ничего не делает с цветом заголовка кнопки.

Я пытаюсь анимировать цвет UIButton Title Color с помощью animateKeyframes, но это ничего не делает, кроме загрузки последнего состояния в анимации, в в этом случае фиолетовый текст. Я использую тот же код для анимации цветов кнопок и цвета фона UIView без каких-либо проблем.

Я проверил и изменил кнопку на пользовательскую кнопку в Interface Builder, но это тоже не помогло.

        UIView.animateKeyframes(withDuration: 12, delay: 12, options: [.allowUserInteraction, .repeat, .autoreverse], animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(blueText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(greenText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(yellowText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(redText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(purpleText, for: UIControlState.normal)
            })
        }, completion: nil)

person Brewski    schedule 29.04.2021    source источник


Ответы (1)


Вызов setTitleColor() внутри блока анимации не работает, потому что UIView.animate работает только с анимируемыми свойствами, такими как infoButton.backgroundColor.

К сожалению, такие свойства кнопок, как tintColor не анимируются. Вы также не должны напрямую обращаться к titleLabel кнопки, которая является nil для системных кнопок.

Вместо этого вы можете использовать UIView.transition с setTitleColor(). Затем вы можете поместить его в Timer... Обычно я не люблю использовать таймеры для анимации, но я не могу придумать другого способа.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    let colors: [UIColor] = [.blue, .green, .yellow, .red, .purple]
    var currentIndex = 0
    
    _ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
        if colors.indices.contains(currentIndex) {
            UIView.transition(with: self.infoButton, duration: 0.5, options: [.transitionCrossDissolve, .allowUserInteraction]) {
                self.infoButton.setTitleColor(colors[currentIndex], for: .normal)
            }
            currentIndex += 1
        } else {
            currentIndex = 0
        }
    }
}

Результат:

Button title color animates and cycles
person aheze    schedule 29.04.2021
comment
Это сработало из коробки, спасибо! - person Brewski; 29.04.2021