Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOs Segue animation left to right (horizontal)

I'm nearly a newbie to Xcode 4. There's a way to add to a segue a custom transition animation that it is not among the four presented by the Interface Builder in the storyboard management? Specifically, i want an animation similar to the normal "cover vertical", but horizontal. I want the a view to pass to another sliding from left to right (or right to left) instead that from up to bottom as it happens in the "cover vertical" transition. I tried with the swipe gesture but no fortune: even that is transitioning from up to bottom and anyway, i don't understand why the defaul transition is from up to bottom when the default transition of all the app usually is right to left or left to right, especially in the case you do swipe...

I tried also a programatically way but no fortune even in this case, using this code:

#import "JHCustomSegue.h"

@implementation JHCustomSegue
- (void) perform {
  UIViewController *src = (UIViewController *) self.sourceViewController;
  UIViewController *dst = (UIViewController *) self.destinationViewController;

  [UIView transitionWithView:src.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
        [src presentModalViewController:dst animated:NO];
    }
    completion:NULL];
}

@end

In the interface builder i defined this class as the class of my segue. Using breakpoint, i saw it enter the function perfom but... don't perform! I've blocked the app in portrait mode (don't know if it's a problem). I tried to run the application on a real ipad and on a simulated iphone. Same Problem.

like image 446
Sasha Grievus Avatar asked Mar 22 '12 16:03

Sasha Grievus


4 Answers

You can use CATransition within a custom Segue to achieve left to right transition. Add this #import "QuartzCore/QuartzCore.h" to your custom Segue

-(void)perform {

__block UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
__block 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];    


}
like image 173
Zakir Hyder Avatar answered Nov 14 '22 18:11

Zakir Hyder


Based on Zakir Hyder's submission, here is the same functionality translated to Swift:

override func perform() {

    var sourceViewController = self.sourceViewController as UIViewController
    var destinationViewController = self.destinationViewController as UIViewController

    var transition: CATransition = CATransition()

    transition.duration = 0.25
    transition.timingFunction = CAMediaTimingFunction(name: 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(destinationViewController, animated: false)     

}
like image 43
Tim Walsh Avatar answered Nov 14 '22 18:11

Tim Walsh


Here is the working code for custom seque when not using navigation controller.

-(void)perform
{

UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];

CATransition* transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom

[destinationController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:destinationController animated:NO completion:nil];
}
like image 8
Sahil Avatar answered Nov 14 '22 20:11

Sahil


Check out this Example on Github:

https://github.com/itinance/iOSCustomSegue

It uses a custom segue from right to left in an example app explicitly without UINavigationController as the thread opener where asking for.

The Code in the answer of Sahil didn't work for me at iOS 8. So i had to investigate a little bit more on this issue.

'UIView animateWithDuration' works on iOS 8, while 'destinationController.view.layer addAnimation:transition' does nothing in combination with presentViewController.

like image 3
itinance Avatar answered Nov 14 '22 18:11

itinance