Custom Segue push weird behavior - iphone

I am trying a simple project (storyboard) where the user swipes from right to left to get to the next view and so on and to go back the user swipes from left to right.
I want to achieve the transition to follow the swipe (L-->R or R-->L).
I have found this:
-(void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.duration = .25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromLeft; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[sourceViewController.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[sourceViewController.navigationController pushViewController:destinationController animated:NO];
}
but this doesn't seem to be doing what is supposed to do.
EXPLAIN:
when i m in landscape (my project only works in landscape) and home button is on the left, the animation comes from the TOP!!!
When I m in landscape and home button is on the right the animation comes from the BOTTOM!!!
Although I have specified it to be from the left.
The other thing is that it changes direction when i use diferent landscapes (homebutton on the left or right).
Any ideas why is this happening???

Are your views in a nav controller?
Have you tried simply using the segue with "push" style?
In your swipe gesture recognizer, just call:
[self performSegueWithIdentifier:#"NextScreenIdentifier" sender:sender];
and you should get the correct behavior (left->right / right->left transition).

ok this is how I did it, although VERY un-orthodox.
Im checking the orientation of the iPad and then instead of going left or right im actually going top/ bottom...
ok this is how I did it, although VERY un-orthodox.
Im checking the orientation of the iPad and then instead of going left or right im actually going top/ bottom...
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
{
//Landscape Left
//.......
transition.subtype = kCATransitionFromTop;
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight)
{
//Landscape Right
//......
transition.subtype = kCATransitionFromBottom;
}

Related

Better NavigationController transition in Three20 using TTURLAction

I am using the following codes to switch controller in my Three20 App
TTURLAction * urlAction = [TTURLAction actionWithURLPath:url];
[urlAction applyAnimated:YES];
CATransition * transition = [CATransition animation];
transition.duration = 0.4f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromRight;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[[TTNavigator navigator] openURLAction:urlAction];
But the transition is strange and never as smooth as the default Three20 transition, e.g. Move from TTTableViewController to TTViewController
Any one can provide a better codes for a smoother transition?
Is it possible to transit only the content between NavigationController and TabBar? (I mean keep the button in existing NavigationController un-touched)
Thanks.
You are in fact animating twice. First you tell three20 to apply animation by [urlAction applyAnimated:YES]; and then you are attaching your own animation.
Remove applyAnimated: and it works just fine. Tested with Three20 1.0.11 on iOS5 Simulator and device.
It might be clever to use [TTNavigator navigator].topController instead of self.navigationController to get the controller which will present the url. This might be an different one under some circumstances.

Customise UINavigationController animation: CATransition

I have an UINavigationController. I made VC1 the rootViewController and programatically load VC2 from VC1 and then have the custom animation to go from VC1 to VC2. Standard. Everything is fine and good.
Now, I would like to have a custom animation between the two like so:
In sum, VC1 slides out of view while VC2 is beneath it. Just like a stack of paper where you slide away the first sheet (VC1) and thus reveal the sheet beneath (VC2).
So what I tried is the following code which is called from VC1 in order to get to VC2. But there are problems with it:
MyVC2 *vctwo = [[[MyVC2 alloc] init] autorelease];
CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromRight;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[[self navigationController] pushViewController:vctwo animated:YES];
The problems are the following:
VC2 is not fixed in the background. It kind of slides in as well (even though I specified kCATransitionReveal). I want to be VC2 totally fixed in the background.
VC1 fades out. I don't really know why. I did not use kCATransitionFade or the like, so I can't see where the fade comes from.
Any suggestions why I am not getting the expected results would be very much appreciated. Sorry if this is obvious, but I am trying this for hours now and got really frustrated.
I think you should use [[self navigationController] pushViewController:vctwo animated:NO]; rather than animated:YES.
I suppose the only way to do this is to forget UINavigationController and come up with my own mechanism to handle everything:
This blog explains how...
So if you wanted to custom animations between VCs, do not use UINavigationController. Here is sample code to swap between two VCs as described above:
-(void)slideDoorOpenTo:(UIViewController *)aController duration:(float)aDuration {
[aController viewWillAppear:YES];
[activeController viewWillDisappear:YES];
//aController.view.alpha = 0.0f;
[self.view insertSubview:aController.view belowSubview:activeController.view]; // so that it is below activeController
[aController viewDidAppear:YES];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:aDuration];
aController.view.transform = CGAffineTransformMakeTranslation(0,0);
activeController.view.transform = CGAffineTransformMakeTranslation(-320,0);
[UIView commitAnimations];
[self performSelector:#selector(animationDone:) withObject:aController afterDelay:aDuration];
}

TabBar always animates to the left when pushing a new viewController

I have a Tab Bar app with a navigation controller on one tab.
I want to push a new view controller, but have it animate in from the left.
What I have is this:
CATransition *transition = [CATransition animation];
transition.duration = 0.8;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
transition.delegate = self;
controller.hidesBottomBarWhenPushed = YES;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[self.navigationController pushViewController:controller animated:YES];
Everything pushes in from the left, except for the tab bar, which always slides out to the left (and transition.duration has no effect on that either).
Is there a way to get the taBar to slide out in the same direction & speed with the rest of the view?
(I've also tried using pushModalViewController, but that has various graphical glitches instead).
It seems to me that you are trying to animate only self.navigationController in your code; since the UITabBar is outside of it, it seems reasonable that it does not get animated as you like (I think it gets animated only as an after effect of animating the inner view, but you have no control on it).
What I would try to do is accessing your UITabBarController's view and add an animation to its CALayer as well (or exclusively to that, you can try different possibilities).

When popping to a previous viewcontroller I get a duplicate of itself during the transition

I am using the following code to popping to a parent view controller (not always the direct parent in the stack), but for some reason I get the current view controller slide in over itself before the parent I am popping to.
CATransition* transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popToViewController:vc animated:YES];
hasPopped = YES;
This appears to be down to the animation code Im using. The only reason I am setting this is because when the app is rotated to landscape the views come in from the bottom on the side. As raised in this question: https://stackoverflow.com/questions/4102345/why-do-views-slide-out-at-the-bottom-when-landscape
I solved this by turning the animated:off during the pop as the assigned animation was providing it

Flip transition in iPhone

I am facing problems in flipping views in iPhone.
I have two views in appDelegate. I want to flip them once user clicks on a button.
I have the following code:
CATransition *transition = [CATransition animation];
transition.duration = 0.75;
[transition #"twist"];
[transition setSubtype:#"fromRight"];
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[transition setFillMode:#"extended"];
[[window layer] addAnimation:transition forKey:nil];
[window addSubview:self.s.view];
[CATransaction commit];
But this is not working. Do anybody knows a better way to flip the views on window side.
What I am doing is calling the method from appDelegate in the respective viewControllers to flip the views.
If you're using the 3.0 SDK and all you want is a simple flip transition (ala the Weather app) then you don't need to go down to CATransition. The higher-level UIView animation transitions will do what you want but with 3.0 there is an even easier way: simply present your new view as a modal view controller and set the modal transition style to flip. From within the first controller:
UIViewController *controllerForSecondView = ..;
controllerForSecondView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controllerForSecondView animated:YES];
Flip back again by using dismissModalViewController.
Documentation Reference
#Luke - thanks, this sample helped me...1 correction though (based on UIViewController.h)
UIViewController *controllerForSecondView = ..;
controllerForSecondView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controllerForSecondView animated:YES];
From the header file comments:
// Defines the transition style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter.
// Defaults to UIModalTransitionStyleSlideVertical.
#property(nonatomic,assign) UIModalTransitionStyle modalTransitionStyle
See The Elements sample code. Particularly AtomicElementViewController -flipCurrentView.