How can I create a horizontal gradient background for my iOS nav bar?

25,079

Solution 1

If you want to programmatically set the gradient of a given UINavigationBar I have a solution for you.

First setup a CAGradientLayer with your desired colors and locations.

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = navigationBar.bounds;
gradientLayer.colors = @[ (__bridge id)[UIColor greenColor].CGColor,
                          (__bridge id)[UIColor blueColor].CGColor ];
gradientLayer.startPoint = CGPointMake(0.0, 0.5);
gradientLayer.endPoint = CGPointMake(1.0, 0.5);

Then grab the UImage for that layer.

UIGraphicsBeginImageContext(gradientLayer.bounds.size);
[gradientLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Set the gradientImage as the backgroundImage for your UINavigationBar.

[navigationBar setBackgroundImage:gradientImage forBarMetrics:UIBarMetricsDefault];

Swift Solution:

[![// Setup the gradient
let gradientLayer = CAGradientLayer()
gradientLayer.frame = navigationBar.bounds
gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

// Render the gradient to UIImage
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

 Set the UIImage as background property
navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)

Result

Solution 2

Updated @JulianM answer for iOS 10 / swift 3.0:

let gradientLayer = CAGradientLayer()
var updatedFrame = self.navigationController!.navigationBar.bounds
updatedFrame.size.height += 20
gradientLayer.frame = updatedFrame
gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
Share:
25,079
Mike
Author by

Mike

Updated on July 14, 2022

Comments

  • Mike
    Mike almost 2 years

    I know how to set a navigation bar background color (with barTintColor), but now I am working on an iOS app that calls for a horizontal gradient (not the typical vertical gradient).

    How can I create a navigation bar with a horizontal gradient background?

  • Mike
    Mike almost 9 years
    THANK YOU! Finally got a chance to implement this and it worked! I first tried adding the layer as a sublayer, but it seemed to conflict with the SVProgressHUD library that I'm using. I was getting the error [SVIndefiniteAnimatedView _barPosition]: unrecognized selector sent to instance. When I tried setting it as a background image as you suggested, it worked!
  • Croisciento
    Croisciento over 8 years
    I'll have to add that this code will not take into account the status bar. If you want to have your gradient take over the whole status bar as well you can simply do something like this : var updatedFrame = navigationBar.bounds updatedFrame.size.height += 20 gradientLayer.frame = updatedFrame