The default navigation bar you get when implementing a UINavigationController
does it’s job but often you want to customize it because it just does not look so fancy.
To customize the background of your UINavigationBar
you set its backgroundImage
property which means you have to provide a UIImage
even if you want to give it a single color.
I created an extension for UIImage
that makes it easy to create instances of UIImage
on the fly.
extension UIImage {
/// This function creates a 1x1 pt colored image
static func withColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
UIGraphicsEndImageContext()
return image
}
}
Code language: JavaScript (javascript)
Now we can use this extension to create a background and use it as a background image for our navigation bar:
/// Declare a white with 0.8 alpha
let background = UIImage.withColor(color: UIColor.white.withAlphaComponent(0.8))
/// Set the color as background
navigationController?.navigationBar.setBackgroundImage(background, for: .default)
navigationController?.navigationBar.setBackgroundImage(background, for: .compact)
Code language: JavaScript (javascript)
If you want to make your navigation bar’s background invisible you can just set it to an empty UIImage
:
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .compact)
Code language: CSS (css)
The shadow of the navigation bar is an image as well. Often you want to make it invisible. You achieve this by setting the shadowImage
property:
navigationController?.navigationBar.shadowImage = UIImage()
Code language: Swift (swift)
If we want to set custom fonts for our navigation bar we cannot do this directly as we would do it when customizing some UILabel
. Instead we do this by setting the navigation bar’s titleTextAttributes
and largeTitleTextAttributes
properties:
/// Setting the font for the centered title
navigationController?.navigationBar.titleTextAttributes = [ NSAttributedString.Key.font: UIFont(named: "someFont")]
/// Setting the font for largeTitles, if enabled via:
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.largeTitleTextAttributes = [ NSAttributedString.Key.font: UIFont(named: "someFont")]
Code language: JavaScript (javascript)
One is still missing, which is the font on the navigation bar’s buttons. I could not manage to set this from within a view controller, for me it was only possible from the AppDelegate. You use the appearance proxy for that which changes the appearance of instances of UIBarButtonItem
for the whole app. Just add the following to your AppDelegate.application(_:didFinishLaunchingWithOptions:)
:
UIBarButtonItem.appearance().setTitleTextAttributes(
[NSAttributedString.Key.font: UIFont(named: "someFont")],
for: .normal)
Code language: CSS (css)