{"id":83,"date":"2020-03-01T20:18:01","date_gmt":"2020-03-01T19:18:01","guid":{"rendered":"https:\/\/mic.st\/blog\/?p=83"},"modified":"2020-03-01T20:18:01","modified_gmt":"2020-03-01T19:18:01","slug":"customizing-your-apps-navigation-bar-titles-buttons-and-background","status":"publish","type":"post","link":"https:\/\/mic.st\/blog\/customizing-your-apps-navigation-bar-titles-buttons-and-background\/","title":{"rendered":"Customizing your app&#8217;s navigation bar titles buttons and background"},"content":{"rendered":"\n<p>The default navigation bar you get when implementing a<code> UINavigationController<\/code> does it&#8217;s job but often you want to customize it because it just does not look so fancy.<\/p>\n\n\n\n<p>To customize the background of your <code>UINavigationBar<\/code> you set its <code>backgroundImage<\/code> property which means you have to provide a <code>UIImage<\/code> even if you want to give it a single color.<\/p>\n\n\n\n<p>I created an extension for <code>UIImage<\/code> that makes it easy to create instances of <code>UIImage<\/code> on the fly.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">extension UIImage {\n<span class=\"hljs-comment\">\/\/\/ This function creates a 1x1 pt colored image<\/span>\n  <span class=\"hljs-keyword\">static<\/span> func withColor(color: UIColor) -&gt; UIImage {\n    <span class=\"hljs-keyword\">let<\/span> rect = CGRect(x: <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-attr\">y<\/span>: <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">1<\/span>, <span class=\"hljs-attr\">height<\/span>: <span class=\"hljs-number\">1<\/span>)\n    UIGraphicsBeginImageContextWithOptions(rect.size, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-number\">0<\/span>)\n    color.setFill()\n    UIRectFill(rect)\n    <span class=\"hljs-keyword\">let<\/span> image: UIImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()\n    UIGraphicsEndImageContext()\n    <span class=\"hljs-keyword\">return<\/span> image\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now we can use this extension to create a background and use it as a background image for our navigation bar:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/\/ Declare a white with 0.8 alpha<\/span>\n<span class=\"hljs-keyword\">let<\/span> background = UIImage.withColor(color: UIColor.white.withAlphaComponent(<span class=\"hljs-number\">0.8<\/span>))\n\n<span class=\"hljs-comment\">\/\/\/ Set the color as background <\/span>\nnavigationController?.navigationBar.setBackgroundImage(background, <span class=\"hljs-attr\">for<\/span>: .default)\nnavigationController?.navigationBar.setBackgroundImage(background, <span class=\"hljs-attr\">for<\/span>: .compact)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you want to make your navigation bar&#8217;s background invisible you can just set it to an empty <code>UIImage<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">navigationController<\/span>?<span class=\"hljs-selector-class\">.navigationBar<\/span><span class=\"hljs-selector-class\">.setBackgroundImage<\/span>(<span class=\"hljs-selector-tag\">UIImage<\/span>(), <span class=\"hljs-selector-tag\">for<\/span>: <span class=\"hljs-selector-class\">.default<\/span>) <span class=\"hljs-selector-tag\">navigationController<\/span>?<span class=\"hljs-selector-class\">.navigationBar<\/span><span class=\"hljs-selector-class\">.setBackgroundImage<\/span>(<span class=\"hljs-selector-tag\">UIImage<\/span>(), <span class=\"hljs-selector-tag\">for<\/span>: <span class=\"hljs-selector-class\">.compact<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The shadow of the navigation bar is an image as well. Often you want to make it invisible. You achieve this by setting the <code>shadowImage<\/code> property:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Swift\" data-shcb-language-slug=\"swift\"><span><code class=\"hljs language-swift\">navigationController?.navigationBar.shadowImage = <span class=\"hljs-type\">UIImage<\/span>()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Swift<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">swift<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If we want to set custom fonts for our navigation bar we cannot do this directly as we would do it when customizing some <code>UILabel<\/code>. Instead we do this by setting the navigation bar&#8217;s <code>titleTextAttributes<\/code> and <code>largeTitleTextAttributes<\/code> properties:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/\/ Setting the font for the centered title<\/span>\nnavigationController?.navigationBar.titleTextAttributes = &#91; NSAttributedString.Key.font: UIFont(named: <span class=\"hljs-string\">\"someFont\"<\/span>)]\n\n<span class=\"hljs-comment\">\/\/\/ Setting the font for largeTitles, if enabled via:<\/span>\nnavigationController?.navigationBar.prefersLargeTitles = <span class=\"hljs-literal\">true<\/span>\nnavigationController?.navigationBar.largeTitleTextAttributes = &#91; NSAttributedString.Key.font: UIFont(named: <span class=\"hljs-string\">\"someFont\"<\/span>)]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>One is still missing, which is the font on the navigation bar&#8217;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 <code>UIBarButtonItem<\/code> for the whole app. Just add the following to your<code> AppDelegate.application(_:didFinishLaunchingWithOptions:)<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">UIBarButtonItem<\/span><span class=\"hljs-selector-class\">.appearance<\/span>()<span class=\"hljs-selector-class\">.setTitleTextAttributes<\/span>(\n<span class=\"hljs-selector-attr\">&#91;NSAttributedString.Key.font: UIFont(named: <span class=\"hljs-string\">\"someFont\"<\/span>)]<\/span>,\n                              <span class=\"hljs-selector-tag\">for<\/span>: <span class=\"hljs-selector-class\">.normal<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>","protected":false},"excerpt":{"rendered":"<p>The default navigation bar you get when implementing a UINavigationController does it&#8217;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&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[3],"tags":[13,14,10,12,11],"class_list":["post-83","post","type-post","status-publish","format-standard","hentry","category-ios-development","tag-appdelegate","tag-customizing","tag-navigation-bar","tag-uinavigationbar","tag-uinavigationcontroller"],"_links":{"self":[{"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/posts\/83","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/comments?post=83"}],"version-history":[{"count":0,"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/posts\/83\/revisions"}],"wp:attachment":[{"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/media?parent=83"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/categories?post=83"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mic.st\/blog\/wp-json\/wp\/v2\/tags?post=83"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}