iphoneuitabbarcontrollercatransition

CATransition not working in UITabBarController (but is working elsewhere)


I'm trying to implement a CATransition in a UITabBarController. Right now, I have a class called FeedViewController. Each tab in the UITabBarController is an instance of this class. In each tab view controller (FirstViewController, SecondViewController, etc) I have code along the lines of:

- (void)viewDidLoad
{
    [super viewDidLoad];
    FeedViewController *feedViewController = [[FeedViewController alloc] initWithNibName:@"FeedViewController" bundle:nil];
    [self addChildViewController: feedViewController];
    feedViewController.view.frame = CGRectMake(0,0,320,self.view.frame.size.height);
    [self.view addSubview: feedViewController.view];
    [feedViewController didMoveToParentViewController: self];
}

Now in FeedViewController I have an IBAction which presents a new view controller. This is the code:

-(IBAction)goHome {
    HomeViewController *home = [[HomeViewController alloc] initWithNibName:nil bundle:nil];
    CATransition *animation = [CATransition animation];
    [animation setDuration:0.3];
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromLeft];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [[self.view.superview layer] addAnimation:animation forKey:@"SwitchToView"];
    [self presentViewController:home animated:NO completion:nil];
}

I've used the exact same CATransition code in other parts of my app before, and it is working fine there. However, in this case there is no animation when the new view is presented. I believe the problem to be the layer where I am adding the animation. Specifically, I believe that I need to replace [self.view.superview layer] with something else, but I don't know what.

Your help is greatly appreciated.

Update:

If I change the animated:NO to animated:YES in the above code, the CATransition does work (but occurs at the same time as the default sliding up animation). This occurs in both iOS 6 and iOS 7.


Solution

  • On the iPhone, a presented view controller always occupies top level. This means that if you say presentViewController:... the new view controller's view replaces the tab bar controller. If that isn't what you want - that is, if you want to perform a transition animation inside a tab - then you will need either to use a view and a transition without the presentViewController:... or else, if you want to use a view controller, then use a custom container controller (and a transition, again without the presentViewController), as I do here:

    https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch06p316containerController/ch19p631containerController/ViewController.m

    If, on the other hand, you are aiming to replacing the whole tab bar controller with a different view controller, then the way to customize that transition in a way that's available on both iOS and iOS 7 is to use a custom container controller as your ultimate root view controller. Now the transition is up to you. That, for example, is what I do in my Albumen app. This consists of three navigation controllers in sequence; tapping a button proceeds to the next navigation controller. Clearly we do not want to use presentViewController: because they will all just pile up on each other; we want to replace the whole navigation controller by another. The structure is similar to the code I just pointed you to; the Ultimate Controller's view occupies the whole screen, and when it is handed a new child view controller it does a transition from its previous child view controller's view to the new child view controller's view, also occupying the whole screen (as a total subview of its own view, don't you see).