Animate barTintColor on push segue

786 views Asked by At

I would like to animate barTintColor property when transitioning from one view controller to another.

I have tried with following solution:

[[self transitionCoordinator] animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    self.navigationController.navigationBar.translucent = NO;
    self.navigationController.navigationBar.barTintColor = [UIColor redColor];
} completion:nil];

which animates barTintColor as it should but my navigation bar should be translucent. To fix this problem I tried to set it to translucent = YES in completion block of trasitionCoordinatoranimation. Like this:

completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    self.navigationController.navigationBar.translucent = YES;
}

but that causes slight jump in barTintColor value of navigation bar after the animation is completed. This is expected since translucent and opaque colors are different.

Similar questions: [1] [2]

Thanks in advance!

EDIT:

I forgot to add that some strange scale animation appears from top left corner in navigation bar if I remove the self.navigationController.navigationBar.translucent = NO; line from animation block. So that's not the solution either.

1

There are 1 answers

1
damirstuhec On BEST ANSWER

I'm going to answer my own question while still being open for other suggestions/solutions.

My solution which I think is quite a "clean one" is to make an alpha blended color from original color with appropriate blend color. So let's say we have a white background behind a navigation bar and we would like to animate current navigation bar barTintColor to green color. In this case we have to blend original green color with white color and appropriate alpha value.

After some playing with values I found out that alpha 0.16 works best for iOS 7 cases (I haven't tested it on other OS versions).

Animation block written in my original question implemented with my solution looks like this:

Pay attention to ALPHA BLENDED ORIGINAL COLOR and ORIGINAL COLOR

[[self transitionCoordinator] animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    self.navigationController.navigationBar.translucent = NO;
    self.navigationController.navigationBar.barTintColor = <ALPHA BLENDED ORIGINAL COLOR>;
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    self.navigationController.navigationBar.barTintColor = <ORIGINAL COLOR>;
    self.navigationController.navigationBar.translucent = YES;
}];

Equation for alpha blending:

CGFloat bR = ((bcR - cR) * alpha + cR);
CGFloat bG = ((bcG - cG) * alpha + cG);
CGFloat bB = ((bcB - cB) * alpha + cB);

values being:

cR, cG, cB     = original color R,G,B components
bcR, bcG, bcB  = blending color R,G,B components
alpha          = alpha value to blend with
================================================
bR, bG, bB     = blended R,G,B components

Anyone who likes this solution is welcome to use a UIColor's category for alpha blending I wrote for this case. You can find it here.

Thanks.