Site icon Dipin Krishna

SwiftUI: Create a Custom Navigation Bar

In this article, we are not customizing a navigation view or a navigation stack. We are simply creating a custom View to be used as a navigation bar.

 

  1. //
  2. //  CustomNavigationBar.swift
  3. //  DK
  4. //
  5. //  Created by Dipin Krishna on 8/23/23.
  6. //
  7.  
  8. import SwiftUI
  9.  
  10. struct CustomNavigationBar: View {
  11.     var leftElement: (any View)? = Text("Back")
  12.     var leftAction: (() -> Void)?
  13.     var rightElement: (any View)?
  14.     var rightAction: (() -> Void)?
  15.     var title: (any View)?
  16.     var inlineTitle: Bool? = true
  17.     var backgroundColor: Color? = Color.black
  18.     var foregroundColor: Color? = Color.white
  19.     var height: CGFloat? = 44
  20.  
  21.     var body: some View {
  22.         VStack (spacing: 0) {
  23.             ZStack (alignment: .top) {
  24.                 HStack {
  25.                     Spacer()
  26.                     if let title {
  27.                         if let inlineTitle, inlineTitle {
  28.                             AnyView(title)
  29.                         }
  30.                     }
  31.                     Spacer()
  32.                 }.background(.clear).frame(maxHeight: .infinity)
  33.  
  34.                 HStack (alignment: .center) {
  35.                     if let leftElement {
  36.                         Button(action: {
  37.                             if let leftAction {
  38.                                 leftAction() // Invoke the left action closure
  39.                             }
  40.                         }) {
  41.                             AnyView(leftElement)
  42.                         }
  43.                     }
  44.  
  45.                     Spacer()
  46.  
  47.                     if let rightElement {
  48.                         Button(action: {
  49.                             if let rightAction {
  50.                                 rightAction() // Invoke the right action closure
  51.                             }
  52.                         }) {
  53.                             AnyView(rightElement)
  54.                         }
  55.                     }
  56.                 }.frame(maxHeight: .infinity)
  57.             }
  58.             .frame(height: height)
  59.  
  60.             if let inlineTitle, !inlineTitle {
  61.                 if let title {
  62.                     HStack {
  63.                         AnyView(title)
  64.                         Spacer()
  65.                     }
  66.                 }
  67.             }
  68.         }
  69.         .padding(.horizontal)
  70.         .background(backgroundColor)
  71.         .foregroundColor(foregroundColor)
  72.     }
  73. }
  74.  
  75.  
  76.  
  77.  
  78. struct CustomNavigationBar_Preview_1: View {
  79.     var body: some View {
  80.         CustomNavigationBar(
  81.             leftElement: Text("Back"),
  82.             leftAction: {
  83.                 // Left Action
  84.             },
  85.             rightElement: Text("Save"),
  86.             rightAction: {
  87.                 // Left Action
  88.             },
  89.             title: Text("Title"),
  90.             backgroundColor: Color.clear,
  91.             foregroundColor: Color.black).padding(0)
  92.  
  93.     }
  94. }
  95.  
  96. struct CustomNavigationBar_Preview_2: View {
  97.     var body: some View {
  98.         CustomNavigationBar(
  99.             leftElement: Text("Back"),
  100.             rightElement: Text("Save"),
  101.             title: Text("Title").font(.subheadline),
  102.             backgroundColor: Color.black,
  103.             foregroundColor: Color.white).padding(0)
  104.     }
  105. }
  106.  
  107. struct CustomNavigationBar_Preview_3: View {
  108.     var body: some View {
  109.         CustomNavigationBar(
  110.             leftElement: Image(systemName: "arrowshape.backward.fill"),
  111.             title: Text("Title")
  112.             .frame(maxWidth: .infinity, alignment: .leading)
  113.             .font(.largeTitle), 
  114.             inlineTitle: false,
  115.             backgroundColor: Color.blue,
  116.             foregroundColor: Color.white).padding(0)
  117.     }
  118. }
  119.  
  120. struct CustomNavigationBar_Preview_4: View {
  121.     var body: some View {
  122.         CustomNavigationBar(
  123.             leftElement: Text("Title")
  124.                 .frame(maxWidth: .infinity, alignment: .leading)
  125.                 .font(.largeTitle),
  126.             rightElement: Text("Close"),
  127.             backgroundColor: Color.red,
  128.             foregroundColor: Color.white).padding(0)
  129.     }
  130. }
  131.  
  132. struct CustomNavigationBar_Preview_5: View {
  133.     var body: some View {
  134.         CustomNavigationBar(
  135.             leftElement: Text("Title")
  136.                 .frame(maxWidth: .infinity, alignment: .leading)
  137.                 .font(.largeTitle),
  138.             rightElement: Image(systemName: "xmark.circle").font(.largeTitle),
  139.             backgroundColor: Color.green,
  140.             foregroundColor: Color.white,
  141.             height: 100).padding(0)
  142.     }
  143. }
  144.  
  145. #Preview {
  146.     VStack (alignment: .leading) {
  147.         CustomNavigationBar_Preview_1()
  148.         CustomNavigationBar_Preview_2()
  149.         CustomNavigationBar_Preview_3()
  150.         CustomNavigationBar_Preview_4()
  151.         CustomNavigationBar_Preview_5()
  152.         Spacer()
  153.     }.padding(0)
  154. }

The above code is self-explanatory with the examples provided.
You can download the file from here: https://github.com/dipinkrishna/swiftui/blob/main/CustomNavigationBar.swift

Hope it helps!

Exit mobile version