I am working on one iPhone application in which I implemented one animation UIViewAnimationTransitionFlipFromLeft. Here my application works fine in the Portrait mode. It is doing the same animation as specified means Flip from Left to Right.
But when I am doing this UIViewAnimationTransitionFlipFromLeft in landscape mode then it is not rotating from left to right. Instead of it is rotating from top to bottom. This is really critical issue. Can you help me out to solve this.
The code I am using for iPhone application to rotate the view is as follows:
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view.window cache:NO];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[UIView commitAnimations];
[self.navigationController pushViewController:objSecond animated:YES];
Thanks,
Best Regards,
Gurpritsingh Saini
If you are using iOS 4.0 or later, the following will do exactly what you want (I just tested it out to make sure)
NewView *myNewView = [[NewView alloc] initWith.....];
[UIView transitionFromView:self.view toView:myNewView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
//[self.navigationController pushViewController:myNewView animated:NO];
[myNewView release];
EDIT: I'm changing the above code a bit (nothing new, just commenting out the navigation controller because it's not necessary for this).
So there are several ways to go about this (as far as keeping track of the next view), but this is the easiest I can think of. You can already switch from view 1 to 2, so I'm going to explain how to get from 2 to 10 (or however many you need).
Basically, the view transition lasts too long for viewDidLoad
to catch a call to go to the next view. So what we need to do is set up a timer that waits and sends a method to switch at a later time. So this is the code you would see in view 2 (and 3 and 4, etc.).
- (void)viewDidLoad {
// this gets called before animation finishes, so wait;
self.navigationController.delegate = self;
// you will need to set the delegate so it can take control of the views to swap them;
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(switchView) userInfo:nil repeats:NO];
}
I only wait 1 second until I call the switch method, but if you are loading a lot into your views, you may want to wait a bit longer. 1.5 seconds should be more than enough, but you can play around with that to see where it works and doesn't work.
Next, you have to call the next view in the switchView
method.
- (void)switchView {
NextView *myNextView = [[NextView alloc] initWith ... ];
[UIView transitionFromView:self.view toView:nextView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
[nextView release];
}
This worked perfectly for me. Just to make sure I was getting new views, I assigned tags to each view and added UILabels as subviews in each view's viewDidLoad
method and each showed the number of its view. So hopefully this is what you needed. I'm sure you have more complex things you will need to do, but this will give you the animation and logic you need to get the look you want. (on a side note, viewDidAppear
doesn't seem to get called when doing this, so it might be necessary to call it manually from viewDidLoad
if you really need to use it, but otherwise it works fine)
You will have to manually add a transformation to your view; the flip transformation always operates as if the view controller were in portrait orientation.
Note that the context argument to +beginAnimations:context:
is not meant to be a CGContextRef
per se. You probably don't want to pass the current graphics context there. Pass NULL
instead.
Try with this :
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
CGFloat startValue = 0.0;
CGFloat endValue = M_PI;
rotateAnimation.fromValue = [NSNumber numberWithDouble:startValue];
rotateAnimation.toValue = [NSNumber numberWithDouble:endValue];
rotateAnimation.duration = 1.5;
[self.view.layer addAnimation:rotateAnimation forKey:@"rotate"];
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[UIView commitAnimations];
I think this will work out.
The Accepted answer by slev did not work for me, I got all sorts of errors after trying the code in my custom Segue. I found a method that not only works but is more precise as it doesn't require the use of a Timer. Here is MySegue.m:
@implementation FlipRightSegue
- (id)initWithIdentifier:(NSString *)iden source:(UIViewController *)sour destination:(UIViewController *)dest
{
self = [super initWithIdentifier:iden source:sour destination:dest];
return self;
}
- (void)perform
{
UIViewController *src = [self sourceViewController];
UIViewController *dst = [self destinationViewController];
//[UIView transitionFromView:src.view toView:dst.view duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:nil];
//[UIView commitAnimations];
[UIView transitionWithView:src.navigationController.view duration:0.8 options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[src.navigationController pushViewController:dst animated:NO];
}
completion:NULL];
}
@end
I also have a second class for flips to the right.
Code was taken from this website: http://www.dailycode.info/Blog/post/2012/11/29/iOS-Custom-Flip-Segue-(portrait-and-landscape-layout)-xcode-4.aspx