skip to Main Content
Custom Gradient Navigation Bar In Swift IOS

Custom gradient navigation bar in iOS using Swift

In this tutorial I’m going to show you the new fancy way of displaying your navigation bar to spice your app’s design a bit. I don’t quite like the original UINavigationBar although it is surely well written and can be customised really well.

 

But what if you want to go beyond that? You wish to display 2 separate UILabels in the center, have a transparent background and use different icons etc. This is exactly when you would go on your own way and create a custom navigation bar using a custom UIView to get all that freedom.

Custom gradient navigation bar

“Let’s get down to business”. What we would like to achieve in this tutorial is to have a transparent navigation bar, with a CAGradientLayer on it, which displays a nice gradient from black to clear color and transitions to a solid background color if you scroll down enough in your UITableView.

Store locator gradient navigation bar CAGradientLayer

What do we need for it?

We’ll need a custom UIView that we can customise and add our CAGradientLayer to it.

Let’s start with the custom view:

Create a new class in Xcode, call it GradientHeaderView and subclass it from UIView.

In this class add a new property and call it: gradientLayer which is a subclass of CAGradientLayer. This layer will be our gradient layer that displays that nice gradient when we don’t want to show the solid background color.

It would be also nice to be able to define some colors for that gradient layer inside Interface Builder, so you can instantly see how your gradient will look like without having to build a new version every time you change colors. With the new version of Xcode you can achieve this effect by using IBDesignable and IBInspectable keys in your classes.

Read more about IBDesignable and IBInspectable here.

IBDesignable and IBInspectable

To be able to modify the colors of the gradient layer we need 2 IBInspectable properties:

topColor – which will be the top/starting color of the gradient

bottomColor – which is the bottom/end color of the gradient

Also will add another one, call it bottomYPoint which will set the last y position of the gradient (if this value is 1.0 the gradient layer will expand through the whole frame of the view that holds it, if 0.5 than it will only expand from the top to the middle of the view’s frame).

 

This is how our code looks like until now.

You’ll notice that each property declares the didSet function, which is getting called every time you modify that property (for example when you modify it in Interface Builder). And since we want our view to reflect that change, we would want to update the UI, hence the updateUI() function. This function will simply call the setNeedsDisplay() function to reload the view.

Create the gradient layer

Of course to make it work, we need to add a gradient layer on top of our view.

So create the gradient layer with the top and bottom colors and set the starting and end points as well. This method will add a CAGradientLayer to our custom UIView but will not handle layout changes, so if we would run this code right now, it would first crash… and then secondly it would look ugly on an iPhone 6, since the width of the gradient would not be equal to the screen’s width.

We can easily solve this by calling the layoutSubviews() function and change the frame of the gradient layer.

Also need to add init methods to add the gradient on the view:

Now we have everything we need to play around with our new custom UIView a.k.a navigation bar, let’s see how it looks right now in Interface Builder.

Interface builder Xcode gradient navigation bar

As you can see you have the option to change the colors and the position of the y value.

Change background color when scrolling

Next thing we would like to achieve is that nice animation that you see in lot of new apps, and also on dribbble.com. We have added this feature into our own app, you can check it out here.

storelocator gradient navigation bar CAGradient layer shops nearby iPhone 6

For this we would 2 functions only.

  1. one that will change the color of our navigation bar from clear to a solid color.
  2. one that will handle the scrolling and set the different color when the offset limit is reached.

 

To complete the first one we need to add a function to our GradientHeaderView.

As its name suggests, when the isClear Boolean is equal to true, it will show the gradient layer and set the background color to a clearColor to show the gradient layer on top of the navigation bar. If the boolean is false, than hide the gradient layer and change the background color to a solid color in our case it is an RGB(54, 54, 54).

Second method we need, is the scrollViewDidScroll that will notify us if the view was scrolled, if so than check if the actual scrolling offset is bigger or equal than our limit (in this case the height of the navigation bar that contains the gradient layer) and call the adjustBackground method.

Just simply add this method into your ViewController.

Hope you enjoyed this tutorial and helped you out a bit to make your iOS app stand out.

Download your project here:

Check out our StoreLocator iOS app template that uses this feature among many more. Create your own iOS app now.

Store Locator iOS app template shop nearby swift
  • Syed Danish Ali

    Hey, Thanks for such a succinct tutorial. I’d be really thankful if you can explain how can one add buttons and other UI elements inside this custom header? I’m a debutant in Swift and Ios.

    • Hey, no worries, glad we could help you out.

      Well there are tons of tutorials our there especially for beginners that I guess covers this topic, but basically you have 2 options:

      Since the header is a normal UIView, you can either drag and drop other UI elements onto this view in Interface builder, or do it programmatically.

      If you wish to program it, than all you have to do is:

      1. create a new object (UIButton, UIView, etc), like: let myNewButton = UIButton()
      2. position it the way you want it (define a frame for your button: myNewButton.frame = CGRectMake(x, y, width, height) or place it with Auto Layout)
      3. define all the properties (background color, textcolor, title…)
      4. add it to the headerview: headerView.addSubview(myNewButton)

  • Frank Buch Larsen

    This could be the dumbest question ever, but I have no idea where I can find an UIView on the navigationcontroller that can be the custom GradientHeaderView class. I can only find the Title UiView, but that isn’t the complete header. Can you point me in the right direction, please?
    Thanks, Frank

    • sabminder

      In this example the navigationBar is completely hidden, and a separate UIView (GradientHeaderView class) is added to the viewController’s view and modified.