22

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?

Andrew
  • 227,796
  • 193
  • 515
  • 708
  • Posting this as a resource, I hope it is of some use. http://stackoverflow.com/questions/19632081/horizontal-cagradientlayer-in-ios-7-0 http://nscookbook.com/2013/04/recipe-20-using-cagradient-layer-in-a-custom-view/ – gwar9 Aug 08 '15 at 04:39

4 Answers4

76

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

Richard Topchii
  • 7,075
  • 8
  • 48
  • 115
JulianM
  • 2,540
  • 18
  • 13
  • 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! – Andrew Aug 14 '15 at 18:56
  • 3
    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` – Croisciento Dec 29 '15 at 09:06
17

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)
Makalele
  • 7,431
  • 5
  • 54
  • 81
1

Swift

Add this function in global class

func setHorizontalGradientColor(view: UIView) {
    let gradientLayer = CAGradientLayer()
    var updatedFrame = view.bounds
    updatedFrame.size.height += 20
    gradientLayer.frame = updatedFrame
    gradientLayer.colors = [UIColor.black.cgColor, UIColor.blue.cgColor]
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
    view.layer.insertSublayer(gradientLayer, at: 0)
}

Use in anywhere:

setHorizontalGradientColor(view: self.bgView)
Deepak Tagadiya
  • 2,187
  • 15
  • 28
0

You can use that :

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"gardientImage"] forBarMetrics:UIBarMetricsDefault];

for ios 7 navigation bar height is 64px

Rohit suvagiya
  • 1,005
  • 2
  • 12
  • 40