holographix
holographix

Reputation: 2557

Force NavigationBar's title to animate

I'm developing a navigation system that drills down three steps and then lets you navigate the contents with arrows that actually just change the contents of that view, so technically the navigationcontroller doesn't receive any pop/push, because of that I as soon as I do a

self.navigationItem.title = [[[self.symbol valueForKey:@"section_title"] uppercaseString]  stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

the title changes as It should but for obvious reasons doen't animate.

Is there a way to force it to animale as if a pop/push action happened? something like:

self.navigationItem.direction = NavigationDirectionLeft;
self.navigationItem.title = @"Whatevah!";

so that as soon as the title changes it make the old title fades out in a transition that goes from left to right and the the title fades in, or way better the new title faded in transitioning from left to right entering from the left side

[FYI I don't need to support ios versions prior to 5.0, so only 5.0 > :)]

Upvotes: 2

Views: 2669

Answers (2)

Ashley Mills
Ashley Mills

Reputation: 53101

OK, this isn't a perfect solution, but might give you a starting point:

Fading between nav bar titles is fairly simple:

CATransition *fade = [CATransition animation];
fade.type = kCATransitionFade;
fade.duration = 2.0;
[self.navigationController.navigationBar.layer addAnimation: fade forKey: @"fadeText"];
self.navigationItem.title = "new Title";

There are other kinds of "out of the box" transitions you can use to animate the position of the title, so for example:

CATransition *push = [CATransition animation];
push.duration = 2.0;
push.type = kCATransitionPush;
push.subtype = kCATransitionFromRight;
[self.navigationController.navigationBar.layer addAnimation: push forKey: @"pushText"];
self.navigationItem.title = "new Title";

The problem with this is that the whole nav bar moves. To get around this you'll need to find the layer for the title label in the navbar's subviews. This view hierarchy is 'private', so you shouldn't go submitting this code to the store, but like I say… this might give you a starting point.

CATransition *fade = [CATransition animation];
fade.type = kCATransitionFade;
fade.duration = 2.0;

CATransition *move = [CATransition animation];
move.duration = 2.0;
move.type = kCATransitionMoveIn;
move.subtype = kCATransitionFromRight;

UILabel * navBarTitleLabel;
for (UIView * view in self.navigationController.navigationBar.subviews) {
    if ([NSStringFromClass(view.class) isEqualToString: @"UINavigationItemView"]) {
        navBarTitleLabel = view.subviews.firstObject;
        break;
    }
}

[navBarTitleLabel.layer addAnimation: fade forKey: @"fadeText"];
[navBarTitleLabel.layer addAnimation: move forKey: @"moveText"];

self.navigationItem.title = newTitle;

You might find that you need to removeAllAnimations from the layer once they're complete. I didn't get a chance to fully test it all out.

Upvotes: 3

iDev
iDev

Reputation: 23278

Try setting a UIView as self.navigationItem.titleView and then create a UILabel and add it as title. When you want to animate, animate this Label over this UIView and add a new UILabel and animate that to replace this. You can use some block based animations for this.

For eg:-

[UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
        label.frame = labelFrame;
    } 
    completion:^(BOOL finished){
        NSLog(@"Done!");
    }];

Upvotes: 1

Related Questions