'Animate a UILabel and UIButton within a single UIView.transition block?
I need to animate the change of the value of a UILabel and a UIButton's image property.
I currently use two UIView.transition blocks which seem to work fine, but it seems awful and Im sure theres a far better way Im missing to avoid having duplicated code. Currently doing this:
UIView.transition(with: label, duration: 1, options: [.curveEaseInOut, .transitionCrossDissolve], animations: {
self.label.text = someText
}, completion: nil)
UIView.transition(with: aButton, duration: 1, options: [.curveEaseInOut, .transitionCrossDissolve], animations: {
self.aButton.setImage(aUIImage, for: .normal)
}, completion: nil)
Afaik theres no init for UIView.transition which takes in an array of UIViews to animate or something similar.
Thanks!
Solution 1:[1]
Concept
Looks like there are no 'built-in' ways to transition multiple views within one UIView.transition
animation block.
Instead, we can try to make our own if we had a way to control transitions without blocks. Enter CATransition
!
You can use CATransition
to add cross-dissolve effects to CALayer
like so:
let transition = CATransition()
transition.duration = 0.3
transition.type = .fade
view.layer.add(transition, forKey: "transition")
Answer
CATransition
objects can be added to multiple layers at the same time. So we can use this knowledge to write our own code that applies this transition to multiple layers (or views) at the same time.
I went ahead and made a UIView
extension for you. The stripped down version looks like this:
extension UIView{
class func groupTransition(
with views: [UIView],
duration: TimeInterval,
animations: (() -> Void)?
){
let transition = CATransition()
transition.duration = duration
transition.type = .fade
for v in views{
v.layer.add(transition, forKey: "transition")
}
animations?()
}
}
You can pass the list of views you want to transition and perform all the transition changes in a single block.
UIView.groupTransition(
with: [label, aButton],
duration: 0.3
) {
self.label.text = self.getRandomText()
self.aButton.setImage(self.getRandomImage(), for: .normal)
}
Discussion
I added some more functionality (like animation curve, delay, etc.) and made a more usable version of this and posted it here.
Of course there are disadvantages with this approach. You lose all the fancy transitions built in such as the "flip" transition. This is because the CoreAnimation Transition API only has some basic (but nice) effects baked in.
Feel free to fork the repo and tweak it for your liking.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |