Standard iOS components can get boring… Luckily, with Swift, customization is available everywhere! This article will demonstrate how to use a custom image for your navigation bar, while still maintaining all the functionality provided in a Navigation Controller. 🚀
TL;DR: Clear the default nav bar image provided by Navigation Controllers using a bit of code and position your image in it’s place by constraining it to the view’s top, leading, and trailing anchors (be sure to not constrain to the safe area).
1. Creating the custom header image
Chances are the custom navigation bar header you have in mind for you app will need to be created manually. There are many ways to go about doing this, but the simplest for my needs could be done using Sketch. Using the vector tool, I was able to create the design I had in mind within a couple minutes. The dimensions here don’t really matter because of the excellent export presets Sketch has by default (the iOS preset provides standard, @2x and @3x sizes Xcode asks you for).
2. Clear the default Navigation Bar image
Assuming you already have a view controller embedded in a Navigation Controller, the next step is to strip the nav bar from the default provided header image. This is fairly straight forward, and can be done in a couple lines of code. Here is the function I use to do so; and note — I put it a
struct for reuse purposes, but this is optional.
And this is how the method is called from the view controller:
The above code snipet should be called from either
viewWillAppear(_:) in order to ensure it is executed before the user sees the view. If you run the app now, you should be able to notice the missing nav bar image. 🔥
3. Insert the custom header image
Now that the navigation bar is clear, we can provide our own image. For the purposes of this article, I will do this using interface builder. This is as simple as dragging a
UIImageView onto your view controller, providing the proper image, and setting the constraints.
In order to set the constraints so that the iPhone X doesn’t clip the image, we need to constrain the
imageView's top anchor to
view's top anchor (not the safe area). In my case, setting the constraints to
0left a small gap along the edges, so a value of
-2 should fix that.
Of course, the height constraint will change depending on the image used. and, since my image is dark, I also went ahead and set the large title text colour to white, and the status bar to
At this point, the custom header should work as intended 🎉
4. Handling device sizing and orientation
You might notice the header image looks fine on the iPhone X, but on any other device it looks way too big. This is because there is a gap between a
view's top anchor and a
view's top safe area anchor on the X. Luckily, can easily adjust the height of the image through an
IBOutlet reference to the heigh constraint of the image view. Full device sizing can be found here. Place this code in the same area we clear the navigation bar default image:
You might also notice the height of the header image height is way too tall when rotating the device to landscape. This can be easily handled in the
willTransform(to:with) method provided in the view controller.
I didn’t include it in my examples, but this will also work with added bar button items to the nav bar. That’s it! Your custom navigation bar image should now work as intended 👌