Reputation: 727
Dear Core Animation/iOS Experts,
I am trying to get an effect similar to the question below.
Core animation animating the layer to flip horizontally
The accepted answer seems to describe exactly what I require, except there is no code with this answer and I can't get any code I write to work.
Here is exactly what I'm trying to do:
1) Have 1 master view controller/view and on a portion of the main view have 2 UIViews which overlap, with only one shown (1 at the 'front' and 1 at the 'back')
2) A separate UIControl/UIButton gets pressed and then a 3D flip transition occurs which rotates the front (visible) view out of view and at same time rotates the back (hidden) view to the front...just like seeing the reverse of a playing card.
3) Be able to keep pressing the UIControl to toggle between the two views
4) Be able to interact with just the controls on the front view (i.e. pressing the front layer won't inadvertently fire a control on the back which happens to lie underneath the tap)
I may be approaching this the wrong way so let me know. Ideally, I would like to use Core Animation, and not the UIView built in flip transactions, as I want the animation to be 3D and also want to use this task as a stepping stone for doing more complex CA stuff.
At the moment I can get the front view to flip nicely (only once) but the back view doesn't show.
Cheers,
Andy
Here is the code I've got:
MainViewController.h
@interface MainViewController : UIViewController
- (IBAction)changeViewTapped:(UITapGestureRecognizer *)recognizer;
@end
MainViewController.m
#import "MainViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface MainViewController ()
@property (weak, nonatomic) IBOutlet UIView *detailView;
@property (weak, nonatomic) IBOutlet UIView *listView;
@property (nonatomic) CATransform3D rotationAndPerspectiveTransform;
@end
@implementation MainViewController
@synthesize detailView = _detailView;
@synthesize listView = _listView;
@synthesize rotationAndPerspectiveTransform = _rotationAndPerspectiveTransform;
- (void)viewDidLoad {
[super viewDidLoad];
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, M_PI, 0.0f, 1.0f, 0.0f);
self.rotationAndPerspectiveTransform = rotationAndPerspectiveTransform;
CALayer *listLayer = self.listView.layer;
listLayer.doubleSided = NO;
listLayer.transform = self.rotationAndPerspectiveTransform;
}
- (IBAction)changeViewTapped:(UITapGestureRecognizer *)recognizer {
CALayer *detailLayer = self.detailView.layer;
CALayer *listLayer = self.listView.layer;
detailLayer.doubleSided = NO;
listLayer.doubleSided = NO;
[UIView animateWithDuration:0.5 animations:^{
detailLayer.transform = self.rotationAndPerspectiveTransform;
listLayer.transform = self.rotationAndPerspectiveTransform;
} completion:^(BOOL finished){
// code to be executed when flip is completed
}];
}
@end
Upvotes: 4
Views: 5386
Reputation: 2530
- (void)perform
{
UIViewController *src = (UIViewController *) self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
[UIView beginAnimations:@"LeftFlip" context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:src.view.superview cache:YES];
[UIView commitAnimations];
[src presentViewController:dst animated:NO completion:nil];
}
Upvotes: 0
Reputation: 4737
A quick tip about the flip animation in iOS -- the system needs time to render the back view (the one that will be flipped to) before you start the flip animation. So if you try to change the contents of that view, and trigger off the flip animation in the same method, you will have problems.
To get around this, I've had success with code like this:
- (void)flipView {
// Setup the view for the back side of the flip
[self performSelector:@selector(performFlip) withObject:nil afterDelay: 0.1];
}
- (void)performFlip {
[UIView transitionWithView: tileToFlip
duration: 0.5
options: UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
// My flip specific code
}
completion:^(BOOL finished) {
}
];
}
In a nutshell, I'm setting everything up in the flipView
method, returning control to iOS so it has time to do it's rendering, then kicking off the flipTile
selector after a tenth of a second to do the actual animation.
Good luck!
Upvotes: 3