4

CATransitions can be used to animate transitions in Navigation Controllers when drilling down. However when using Back button og Navigation Controller (going back up) animation is still slide out. Does anyone know how to attach CATransition to the Back button of Navigation Controller? thanks.

Code used to animate when "drilling down":

CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromTop;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
Tommy Herbert
  • 20,407
  • 14
  • 52
  • 57
vilo
  • 51
  • 1
  • 6

5 Answers5

7

There is no need to create a custom button... You can simply do something like this:

- (void)viewWillDisappear:(BOOL)animated
{
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
        // back button was pressed.  We know this is true because self is no longer
        // in the navigation stack.  
        CATransition *transition = [CATransition animation];
        [transition setDuration:0.75];
        [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [transition setType:@"oglFlip"];
        [transition setSubtype:kCATransitionFromLeft];
        [transition setDelegate:self];
        [self.navigationController.view.layer addAnimation:transition forKey:nil];
    }

    [super viewWillDisappear:animated];
}

Edit: you must add the quartz framework first in order to use CATransition

Tim
  • 162
  • 5
shadowfax
  • 269
  • 1
  • 3
  • 5
  • I just tried this and worked out of the box (nice animation and all :-) Will this go through apple's review? Why this overrides the custom navigation's animation? (I mean, I'm glad it does, but wouldn't have said so based on the code) – alasker Sep 12 '14 at 13:41
6

For adding animation to the back button, you have to create your own back button, and on the back button action specify the animation you want.

  1. Adding a back button to the navigation bar: add this line to your viewDidLoad method:

    self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(back)];
    
  2. In the back method add this code:

    CATransition *transition = [CATransition animation];
    transition.duration = 1;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromBottom;
    transition.delegate = self;
    [self.navigationController.view.layer addAnimation:transition forKey:nil];
    [self.navigationController popViewControllerAnimated:YES];
    
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Mandar Khole
  • 81
  • 2
  • 5
  • The answer posted by shadowfax didn't completely remove the slide animation done by the presenting view controller. Using this answer (custom back button) worked best to replace the animation, although I now have to provide a custom back button image. – Richard McCluskey Nov 26 '14 at 19:51
0

I'm not sure I understand the question. UINavigationController already uses a slide transition when switching views. If you want to attach a custom transition to the back button, you're going to have to create a custom back button and connect it to an action that will run your CATransition code.

indragie
  • 18,002
  • 16
  • 95
  • 164
  • That's the thing. UINavigationController uses slide transitions and I need it to flip. – vilo Jul 07 '10 at 08:28
0

If you want animation like back button of navigation controller bar just put following code in your action.

[self.navigationController popViewControllerAnimated:YES];

0

Swift 3 version of shadowfax answer:

    let transition:CATransition = CATransition.init()
    transition.duration = 0.75
    transition.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = "oglFlip"
    transition.subtype = kCATransitionFromRight
    //transition.delegate = self // not needed
    self.navigationController?.view.layer.add(transition, forKey:nil)
smukamuka
  • 1,442
  • 1
  • 15
  • 23