BrownEye
BrownEye

Reputation: 979

Xcode custom segue - Opposite of Cover Vertical (top to bottom) - COMPLETE NEWBIE

I have been trying for some time to create a custom segue that does the opposite of the cover vertical (to create a from top to bottom effect animation).I had looked through other questions, google and youtube but cannot get it working.I am completely new to the classes etc. so any help in a step by step guide or video would be so good. I believe that this URL is trying to do something similar to what I want:

http://jrwren.wrenfam.com/blog/2012/02/01/storyboard-custom-segue-for-custom-pushviewcontroller-animation/ , I just cannot get it working.

If any of you know a way to create a segue that is a top to bottom version of the cover vertical segue could you please help me out?

Upvotes: 8

Views: 9924

Answers (7)

fredericdnd
fredericdnd

Reputation: 1008

I advise you to use the Hero library to achieve this. It adds a lot of animations and transitions, notably between view controllers : https://github.com/lkzhao/Hero/blob/master/README.md There is an transition called "Cover", and you can choose the direction (left, top, right, bottom)

Upvotes: 0

coco
coco

Reputation: 3136

Building on @dmason82's answer, translating to Swift, and simplifying a little, this works for me:

class UIStoryboardSegueFromTop: UIStoryboardSegue {
    override func perform() {
        let src = self.sourceViewController as UIViewController
        let dst = self.destinationViewController as UIViewController

        src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
        dst.view.transform = CGAffineTransformMakeTranslation(0, -src.view.frame.size.height)

        UIView.animateWithDuration(1.0, animations: {
            dst.view.transform = CGAffineTransformMakeTranslation(0, 0)

            }) { (Finished) in
                src.presentViewController(dst, animated: false, completion: nil)
        }
    }
}

Upvotes: 3

kanstraktar
kanstraktar

Reputation: 5357

To complete dmason's answer and have your controller unwind in the opposite direction - going back up from where it came, do this in the presented view controller:

[UIView animateWithDuration:0.75
                      delay:0.0
                    options:UIViewAnimationOptionTransitionFlipFromBottom
                 animations:^{
                     [self.view setTransform:CGAffineTransformMakeTranslation(0, -self.view.frame.size.height)];
                 }
                 completion:^(BOOL finished){
                     [self dismissViewControllerAnimated:NO completion:nil];
                 }
 ];

Bergy's answer didn't work for me.

Upvotes: 1

Victor Carreño
Victor Carreño

Reputation: 230

Here is my implementation of an Opposite Cover Vertical Segue using Storyboards

https://github.com/viccarre/OppositeCoverVerticalSegue

Upvotes: 2

user3650227
user3650227

Reputation:

Hi I just tried the two other answer but it doesn't work as you ask. In order to create a custom segue looking the exact reverse of cover vertical (modal segue default) I created this code :

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


[sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
[destinationViewController.view addSubview:sourceViewController.view];
[sourceViewController.view setTransform:CGAffineTransformMakeTranslation(0, 0)];
[sourceViewController.view setAlpha:1.0];

[UIView animateWithDuration:0.75
                      delay:0.0
                    options:UIViewAnimationOptionTransitionFlipFromBottom
                 animations:^{
                     [sourceViewController.view setTransform:CGAffineTransformMakeTranslation(0,destinationViewController.view.frame.size.height)];
                     [sourceViewController.view setAlpha:1.0];
                 }
                 completion:^(BOOL finished){
                     [sourceViewController.view removeFromSuperview];
                     }];

}


@end

Upvotes: 1

bergy
bergy

Reputation: 1485

dmason's answer is great, and if you want to add an unwind segue so your modal animates properly when it's closed, your perform action could look like this (in a new custom segue class)

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

    [sourceViewController dismissViewControllerAnimated:NO completion:nil];
    [destinationViewController.view addSubview:sourceViewController.view];

    [UIView animateWithDuration:0.75
                     animations:^{
                         sourceViewController.view.center = CGPointMake(sourceViewController.view.center.x, sourceViewController.view.center.y-600);
                     }
                     completion:^(BOOL finished){
                         [sourceViewController.view removeFromSuperview];
                     }
     ];
}

Upvotes: 0

dmason82
dmason82

Reputation: 399

Well, you would want to create a subclass of UIStoryBoardSegue, like the walkthrough shows you, however under the Storyboard class' .m file(implementation) you would want the following code as your -(void)perform: method -

-(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 setTransform:CGAffineTransformMakeTranslation(0, -sourceViewController.view.frame.size.height)];
[destinationViewController.view setAlpha:1.0];

[UIView animateWithDuration:0.75
                      delay:0.0
                    options:UIViewAnimationOptionTransitionFlipFromTop
                 animations:^{
                     [destinationViewController.view setTransform:CGAffineTransformMakeTranslation(0, 0)];
                     [destinationViewController.view setAlpha:1.0];
                 }
                 completion:^(BOOL finished){
                     [destinationViewController.view removeFromSuperview];
                     [sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
                 }];}

Hopefully this is helpful.

Upvotes: 8

Related Questions