I always used to use the following code to make a flip animation between one view and the other:
[UIView transitionFromView:firstView
toView:secondView
duration:0.6
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished) {
// finish code here
}];
This worked fine, giving a natural-looking flip.
But when I used it on the view that was defined on a storyboard using Auto Layout things started getting messy - the views were resized and moved after this animation.
Is there any way to animate this kind of flip by animating constraints?
Auto Layout can only be used to position and resize views. It cannot be used to produce the kind of Core Animation transform needed to produce the flip transition effect. So the short exact answer is no, there is no way to animate this kind of flip by animating constraints.
However, there is a simple way to modify the code you are already using so that it is consistent with Auto Layout. The way to do it is (1) to add both your firstView
and secondView
to your view hierarchy before you order the animation, (2) to ensure that you've added Auto Layout constraints that define the layout of both those views, and (3) to add an option to the animation so that you are only showing/hiding the two views, rather than tearing down and setting up a new view hierarchy.
In other words you want something like:
// assert: secondView added to view hierarchy
// assert: secondView.hidden == true
// assert: secondView has correct constraints
[UIView transitionFromView:firstView
toView:secondView
duration:0.6
options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionShowHideTransitionViews
completion:nil];
Why is this what's needed? The reason is that, without the UIViewAnimationOptionShowHideTransitionViews
option, the method transitionFromView:toView:duration:options:completion:
will actually manipulate the view hierarchy and add the new destination view. If Auto Layout is engaged, then it won't be laid out correctly since it won't have constraints.
You can see an example project showing this approach working here: https://github.com/algal/AutoLayoutFlipDemo
Alternatively, you can also use your existing call to transitionFromView:toView:duration:options:completion:
. But if you're not going to just show a destination view that already had constraints in place, then you need to use the completion block to add those constraints, as follows:
[UIView transitionFromView:firstView
toView:secondView
duration:0.6
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished) {
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:secondView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:secondView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1 constant:0]];
}];
A working example of this approach is here: https://github.com/algal/AutoLayoutFlipDemo2
My best guess will be that animation is performed via animating layer's ~transform, and that transform is applied from the point where anchorPoint position goes. You could try to solve it in two ways:
First: Make sure you position your views via center constraints, ie. align center of the views which are being transformed (not left or top or trailing and stuff). For example, if both views will have, say "horisontaly + vertically" centered in superview this (not sure) could help.
Second: Create a wrapper view, put those views as subviews and disable autolayout for them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With