I have an iOS UIView with UIViewAnimationTransitionFlipFromRight
. I need it to flip vertically though. The page curl transition won\'t cut it. I assume this wil
Swift 4.0 Version 100% Working Solution
// view1: represents view which should be hidden and from which we are starting
// view2: represents view which is second view or behind of view1
// isReverse: default if false, but if we need reverse animation we pass true and it
// will Flip from Left
func flipTransition (with view1: UIView, view2: UIView, isReverse: Bool = false) {
var transitionOptions = UIViewAnimationOptions()
transitionOptions = isReverse ? [.transitionFlipFromLeft] : [.transitionFlipFromRight] // options for transition
// animation durations are equal so while first will finish, second will start
// below example could be done also using completion block.
UIView.transition(with: view1, duration: 1.5, options: transitionOptions, animations: {
view1.isHidden = true
})
UIView.transition(with: view2, duration: 1.5, options: transitionOptions, animations: {
view2.isHidden = false
})
}
Call of the function:
anim.flipTransition(with: viewOne, view2: viewTwo)
anim.flipTransition(with: viewTwo, view2: viewOne, isReverse: true)
Best practice will be to create UIView
extension and hold this function to that extension so it will be accessible to any UIView
child object. This solution also can be written using completionBlock.
UIViewAnimationOptionTransitionFlipFromTop is easy to use, but we can not create an interactive transition using UIViewAnimationOptionTransitionFlipFromTop. We need change layer’s transform to create an interactive transition.
Just create a transform using CATransform3DMakeRotation is not enough, no light effect, no perspective. I write an sample to add these effect. You can change it to an interactive transition easily.
Demo:
Sample code:
CALayer *sideALayer = sideAView.layer;
CALayer *sideBLayer = sideBView.layer;
CALayer *containerLayer = containerView.layer;
sideALayer.opacity = 1;
sideBLayer.opacity = 0;
sideBLayer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
containerLayer.transform = CATransform3DIdentity;
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = -1.0 / containerViewWidth;
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
sideALayer.opacity = 0;
containerLayer.transform = CATransform3DConcat(perspectiveTransform,CATransform3DMakeRotation(M_PI_2, 0, 1, 0));
}];
[UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
sideBLayer.opacity = 1;
containerLayer.transform = CATransform3DConcat(perspectiveTransform, CATransform3DMakeRotation(M_PI, 0, 1, 0));
}];
} completion:nil];
sideAView and sideBView are subviews of containerView.
The containerView is set a black background.