2

I am using a UIViewController and I use presentModalViewController:controllerr animated:YES to present it but I would like if it would slide down from the top of the screen instead of up from the bottom, any way to do this?

Aspyn
  • 647
  • 1
  • 10
  • 25

5 Answers5

7

I created a function for pushing the ViewControllers from all 4 directions:

- (void) slideLayerInDirection:(NSString *)direction andPush:(UIViewController *)dstVC {
  CATransition* transition = [CATransition animation];
  transition.duration = 0.5;
  transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  transition.type = kCATransitionPush;
  transition.subtype = direction;
  [self.view.layer addAnimation:transition forKey:kCATransition];
  [self pushViewController:dstVC animated:NO];
}

The header file contains the following:

#import <QuartzCore/QuartzCore.h>

#define direction_left kCATransitionFromLeft
#define direction_top kCATransitionFromBottom
#define direction_right kCATransitionFromRight
#define direction_bottom kCATransitionFromTop
Mihriban Minaz
  • 3,043
  • 2
  • 32
  • 52
Amarsh
  • 11,214
  • 18
  • 53
  • 78
  • You are using push, but the original question refers to modal presentation style. Do you know if this could be adjusted to work? – Mihai Timar Aug 08 '13 at 22:02
  • I am using the same code in top-to-bottom and bottom-to-top transitions, which looks like a Modal. – Amarsh Aug 08 '13 at 22:31
  • If you get a black flash while transitioning, just change the window color to solid background color of destination view controller in app delegate (self.window.backgroundColor = [UIColor whiteColor];). – Pawan Rai Nov 13 '16 at 18:26
6
public extension UINavigationController {

    func pushViewControllerFromTop(viewController vc: UIViewController) {
        vc.view.alpha = 0
        self.present(vc, animated: false) { () -> Void in
            vc.view.frame = CGRect(x: 0, y: -vc.view.frame.height, width: vc.view.frame.width, height: vc.view.frame.height)
            vc.view.alpha = 1
            UIView.animate(withDuration: 1, 
                           animations: { () -> Void in
                               vc.view.frame = CGRect(x: 0, y: 0, width: vc.view.frame.width, height: vc.view.frame.height)
                           }, 
                           completion: nil)
        }
    }

    func dismissViewControllerToTop() {
        if let vc = self.presentedViewController {
            UIView.animate(withDuration: 1, 
                           animations: { () -> Void in
                               vc.view.frame = CGRect(x: 0, y: -vc.view.frame.height, width: vc.view.frame.width, height: vc.view.frame.height)
                           }, 
                           completion: { complete -> Void in
                               if complete {
                                   self.dismiss(animated: false, completion: nil)
                               }
                           })
        }
    }
}
Whitney Foster
  • 711
  • 11
  • 17
3

I use the following code to animate a viewController in from the top.

[self.mainViewController.view addSubview:modalViewController.view];
modalViewController.view.frame = CGRectMake(modalViewController.view.frame.origin.x,
                                            -modalViewController.view.frame.size.height,
                                            modalViewController.view.frame.size.width,
                                            modalViewController.view.frame.size.height);

[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){

    modalViewController.view.frame = CGRectMake(modalViewController.view.frame.origin.x,
                                                0,
                                                modalViewController.view.frame.size.width,
                                                modalViewController.view.frame.size.height);

} completion:^(BOOL finished){

    [modalViewController.view removeFromSuperview];
    [self.mainViewController presentViewController:modalViewController animated:NO completion:nil];

}];

It adds the UIView of the modalViewController to the mainViewController, animates it in, then removes the UIView from the mainViewController and presentsViewController: without animation.

Roland Keesom
  • 8,180
  • 5
  • 45
  • 52
  • There's a glitch when you slow down animations. Between removeFromSuperview and presentViewController in the animation completion, the controller's view isn't visible, like a blink :( – Bejil Jan 29 '19 at 10:51
0

You have to #import the QuartzCore framework and add the transition animation, then change:

animated:YES to: animated:NO.

0

What you're describing isn't a built-in transition style; see here for a list of those that Apple provides. If you absolutely need your view controller to appear this way, you'll have to animate it yourself.