Here is a overloaded UINavigationBar
class using a two point gradient, although it could easily be improved to cover multi-point gradients.
To enable this bar style, select the navigation bar object in the navigation scene of the storyboard, and set its custom class to GradientNavigationBar
.
In this case the awakeFromNib
call is used to change the background, (assuming that the Navigation bar class has been changed in the storyboard), in the case that the Navigation bar is instantiated programatically, the customization call should be made in the appropriate position in the code.
The solution works by converting the colors passed to it to an array of CGFloat
, then generating a CGGradientRef
object, using those colors, creating an image and then using the setBackgroundImage:forBarMetrics
call to set the background as required.
@interface GradientNavigationBar
@end
@implementation GradientNavigationBar
-(void) awakeFromNib {
[self setGradientBackground:[UIColor redColor]
endColor:[UIColor yellowColor]];
}
-(void) setGradientBackground:(UIColor *) startColor endColor:(UIColor *) endColor {
// Convert the colors into a format where they can be used with
// core graphics
CGFloat rs, gs, bs, as, re, ge, be, ae;
[startColor getRed:&rs green:&gs blue:&bs alpha:&as];
[endColor getRed:&re green:&ge blue:&be alpha:&ae];
CGFloat colors [] = {
rs, gs, bs, as,
re, ge, be, ae
};
// Generate an Image context with the appropriate options, it may
// be enhanced to take into account that Navbar heights differ
// eg between landscape and portrait in the iPhone
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
CGContextRef gc = UIGraphicsGetCurrentContext();
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
// The gradient element indicates the colors to be used and
// the color space
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
// Draw the gradient
CGContextDrawLinearGradient(gc, gradient, CGPointMake(0, 0),CGPointMake(0, self.bounds.size.height),0);
// Capture the image
UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
// The critical call for setting the background image
// Note that separate calls can be made e.g. for the compact
// bar metric.
[self setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
CGGradientRelease(gradient), gradient = NULL;
UIGraphicsEndImageContext();
}
@end