How to change the transition animation from bottom to top in navigation controller?

11,259

Solution 1

Replace the code between [UIView beginAnimations:nil context:nil]; and [UIView commitAnimations]; (including those two lines as well) with the following:

CGAffineTransform baseTransform = destView.transform; //1
destView.transform = CGAffineTransformTranslate(baseT,0,destView.bounds.size.height); //2

[UIView animateWithDuration: 0.5 animations:^{ 
    destView.transform = baseTransform; //3
}];
  1. Make a reference of the original transform.
  2. Push our view down without an animation so we can animate it back up
  3. Set the original transform back to the view. This time, it'll animate

You can further add the delay, options and completion parameters to that UIView Animation method. Xcode will probably help you with the autocompletes on those.

Solution 2

Well you are nearly there.

You need to change two things mainly:

1 Change the initial position of the view. You want the view to appear from bottom to top, so initially your view should be at the bottom. This piece of code should be written before the animation.

[destView setTransform:CGAffineTransformMakeTranslation(0, -1000)];

2 Then you need to slide from bottom to the original position , hence inside the animation block:

 [destView setTransform:CGAffineTransformMakeTranslation(0, 0)];

One more suggestion, I guess you are using a newer version of iOS(above iOS4) instead of using animation blocks use UIView's animation method

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

For further info, refer description.

EDIT :
According to your edit on question, you are looking to change the transition animation for NavigationController in the app using storyboard. For that you could use Custom Segue. You will have to create a custom segue, a class that subclasses UIStorySegue and override its perform method like this:

-(void)perform {
    //UIViewAnimationOptions options;
    UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
    UIViewController *destinationController = (UIViewController*)[self destinationViewController];

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

    [destinationController.view.layer addAnimation:transition forKey:kCATransition];
    [sourceViewController presentViewController:destinationController animated:NO completion:nil];
}

You have to change the segue class to this custom segue in storyboard as well, to make it function.

Solution 3

Try using transition effects

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"alarmSegue"]) {


        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];

        tab2ViewController *destViewController = segue.destinationViewController;
        UIView *destView = destViewController.view;
        destViewController.selectionName = @"alarms";

        [sender setEnabled:NO];

         }
     }
Share:
11,259
Niraj Burde
Author by

Niraj Burde

Software Engineer / Performance Optimization Skills: JavaScript / jQuery / ExtJS MongoDB Dev / MongoDB Sharding(Clustering) / MongoDB Administration / MySQL PHP / JAVA / NodeJS / Android Domains: Master Data Processing (High Performance Application) Social Network eLearning

Updated on June 05, 2022

Comments

  • Niraj Burde
    Niraj Burde almost 2 years

    I am new to iOS. I am trying to change the transition animation in navigation controller to load a new UIView controller from bottom to top, using Segue. I believe it will not be too hard to implement but may be I am not able to understand it.

    I could not find any solution in other posts.

    Here's the code I've been trying:-

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"alarmSegue"]) {
        tab2ViewController *destViewController = segue.destinationViewController;
        UIView *destView = destViewController.view;
        destViewController.selectionName = @"alarms";
    
        [sender setEnabled:NO];
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:1.0];
        [UIView animateWithDuration:0.0
                              delay:0.0
                            options: UIViewAnimationOptionCurveLinear
                         animations:^{
                             [destView setTransform:CGAffineTransformMakeTranslation(0, -1000)];
                             //[destView setFrame:CGRectMake(0, 440, 400, 45)];
                             //destView.frame = CGRectMake(0, 0, 320, 460);
                         }
                         completion:^(BOOL finished){
                             [sender setEnabled:YES];
                         }];
        [UIView commitAnimations];
    
    
         }
     }
    

    I just want to implement a SIMPLE transition from bottom to top, using Segue. I want to set some properties of destination controller as well.

  • Niraj Burde
    Niraj Burde about 10 years
    I'm trying. Could you please tell me what is "direction" in the transition.subtype ?
  • Himanshu Joshi
    Himanshu Joshi about 10 years
    Put it like as string @"left" or @"top"
  • Niraj Burde
    Niraj Burde about 10 years
    Thanks! I got it. But what I'm trying is to open a new view which will animate from bottom to top, a simple animation like the default (which is right to left).
  • Himanshu Joshi
    Himanshu Joshi about 10 years
    @NirajBurde does it not opening the new view in similar manner
  • Niraj Burde
    Niraj Burde about 10 years
    it animated the transition of current view when going off the screen
  • Niraj Burde
    Niraj Burde about 10 years
    yes I tried [destView setTransform:CGAffineTransformMakeTranslation(0, 0)]; and then the first line 2nd parameter being -1500. It works but while our animation, default animation from right to left is visible. Can we stop that?
  • Niraj Burde
    Niraj Burde about 10 years
    @ HimanshuJoshi I want the new view to load from bottom of the screen to the top.
  • Niraj Burde
    Niraj Burde about 10 years
    After animating, segue is not performed, and so the properties which are required at destination controller is not received. How can I perform segue with animation?
  • Puneet Sharma
    Puneet Sharma about 10 years
    are you using a navigation controller? If yes, then you are asking a wrong question. You should then look for, how to change the transition animation in navigation controller. the solution I pasted would be more useful in case you are adding the view as a subview on another view
  • Niraj Burde
    Niraj Burde about 10 years
    oh is it! Let me change the question then. And as you have got the idea what I have been trying to achieve, can you help me with that then?