Reputation: 3246
I'm trying to create an animation with two views and I've encountered some unexpected behaviors while performing them.
I want to animate both views position while doing a second animation which is transitionFlipFromBottom
Here's the code:
let initialFrame = CGRect(x: xpos, y: -310, width: 300, height: 300)
let firstView = UIView()
firstView.backgroundColor = .red
firstView.frame = initialFrame
let secondView = UIView()
secondView.backgroundColor = .white
secondView.frame = initialFrame
secondView.isHidden = false
self.view.addSubview(firstView)
self.view.addSubview(secondView)
// Here I try to move the views on screen while fliping them
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut, animations: {
secondView.center = self.view.center
firstView.center = self.view.center
self.flip(firstView: firstView, secondView: secondView)
}, completion: nil)
// This function flips the views vertically while it animates the transition from the first to the second view
fileprivate func flip(firstView: UIView, secondView: UIView) {
let transitionOptions: UIViewAnimationOptions = [.transitionFlipFromBottom, .showHideTransitionViews]
UIView.transition(with: firstView, duration: 0.5, options: transitionOptions, animations: {
firstView.isHidden = true
})
UIView.transition(with: secondView, duration: 0.5, options: transitionOptions, animations: {
secondView.isHidden = false
})
}
The code above fails to execute both animations at the same time.
It only works if I place the flip
function call inside the completion
block, after the first animation (moving frame) finishes, as the following:
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut, animations: {
secondView.center = self.view.center
firstView.center = self.view.center
}, completion: {(_) in
self.flip(firstView: dummyView, secondView: newGroupView)
})
I have even tried to use UIView.animateKeyframes
but it still doesn't work.
Am I missing something here?
Thank you.
Upvotes: 5
Views: 5759
Reputation: 437552
A couple of things:
In transition
, specify .allowAnimatedContent
option.
Defer the animation:
DispatchQueue.main.async {
UIView.animate(withDuration: 1, delay: 0, options: [.curveEaseOut], animations: {
secondView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
firstView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
self.flip(firstView: firstView, secondView: secondView)
}, completion: { _ in
})
}
Somewhat unrelated, you don't want:
secondView.center = self.view.center
Instead, do:
secondView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
You want to set secondView.center
in the coordinate space of the bounds
of view
, not in view
's superview
.
Upvotes: 4