user1130050
user1130050

Reputation: 61

How to code a custom segue that "slides" between View Controllers?

I built a app with storyboard, with an initial view controller, connected to many subsequent view controllers, connected sequentially, using cross dissolve segue. These work one swipes. All works fine. However, instead of being forced to use the basic segues, I want to have a custom segue that will slide the view controller content on and off the screen, much like the push for navigationControllers, but, being enabled to go left and right depending if one is going forward or backwards in the app.

I have set the segue to custom, and have created and saved a MySegue.h file. HOWEVER, I don't know how to code a custom segue that will slide one viewcontroller off the screen as the other slides on and back and forth as I move between view controllers.

Can anyone please provide me with come coding (it should be easy!) for a custom segue to move from one view controller to the next and back by sliding the screen on and off so I don't have to use the basic cross dissolve or standard flips offered in Xcode 4.2? I would be most grateful.

Upvotes: 6

Views: 5947

Answers (3)

dlp
dlp

Reputation: 581

To create a custom segue that slides view controllers first create a class that extends UIStoryboardSegue, then override the perform selector. I just made something like this and it should work for you too. Here's my code:

#define kAnimationDuration 0.5

#import "CustomSlideSegue.h"

@implementation CustomSlideSegue

- (void)perform
{
    UIViewController *sourceViewController = (UIViewController *) self.sourceViewController;
    UIViewController *destinationViewController = (UIViewController *) self.destinationViewController;

    [sourceViewController.view addSubview:destinationViewController.view];
    [destinationViewController.view setFrame:sourceViewController.view.window.frame];

    [destinationViewController.view setBounds:sourceViewController.view.bounds];
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;

    if ( !self.slideLeft ) {
        [UIView animateWithDuration:kAnimationDuration
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             [destinationViewController.view setCenter:CGPointMake(screenSize.height + screenSize.height/2, screenSize.height/2 - 138)];
                             [destinationViewController.view setCenter:CGPointMake(screenSize.width/2 + 127, screenSize.height/2 - 138)];
                         }
                         completion:^(BOOL finished){
                             [destinationViewController.view removeFromSuperview];
                             [sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
                         }];
    } else {
        [UIView animateWithDuration:kAnimationDuration
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             [destinationViewController.view setCenter:CGPointMake(-1*screenSize.height/2, screenSize.height/2 - 138)];
                             [destinationViewController.view setCenter:CGPointMake(screenSize.width/2 + 127, screenSize.height/2 - 138)];
                         }
                         completion:^(BOOL finished){
                             [destinationViewController.view removeFromSuperview];
                             [sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
                         }];
    }
}

Then when you want to perform the segue use this code:

   UIViewController *destination = [self.storyboard instantiateViewControllerWithIdentifier:@"some identifier"];
   CustomZoomSegue *segue = [[CustomZoomSegue alloc] initWithIdentifier:@"segue vc identifier" source:self destination:destination];
   [self prepareForSegue:segue sender:self];
   [segue perform];

The CGPointMake calls are custom to my code (I used landscape orientation) but you should be able to change it to fit your needs. If you need further clarification or have any question let me know and I will try to answer.

NOTE: I use storyboards with no segue lines between the view controllers.

Upvotes: 2

anthonylawson
anthonylawson

Reputation: 781

I was running into the same issue here, but I was using swipe gestures to go from one view controller to the next. Using the storyboard itself to set up segues was working fine, but when I needed a swipe to "go back" to the previous view controller, the animation went from right-to-left, instead of left-to-right. To fix that issue I did the following:

  1. Embedded a Navigation Controller in the root view controller.
  2. Used segues to push new view controllers.
  3. When I wanted to "go back" to the previous view controller, I did not add a segue to the storyboard to push the previous view controller. Instead, I called the Navigation Controller's popViewControllerAnimated method whenever a back swipe occurred.

Upvotes: 4

Sherman Lo
Sherman Lo

Reputation: 2759

Why not just use a UINavigationController? This seems to be exactly what they're designed for.

Upvotes: 0

Related Questions