5

In iOS SwiftUI, how can we make a common layout for the navigation bar, so we can use that in all projects without rewriting the same code?

Enter image description here

We can use ViewBuilder to create a base view for common code as follows:

struct BaseView<Content: View>: View {
    let content: Content
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    var body: some View {
        // To-do: The most important part will go here
    }
}

How can we add navigation bar code in View Builder or base view?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GrayFox
  • 101
  • 1
  • 9
  • Did you try to define the navigation bar in a different struct view and use it as an overlay in different views? – arata Jan 25 '22 at 17:08
  • No, i haven't tried that approach. I had tried to add Navigation bar in Base view, but this approach is not working. – GrayFox Jan 25 '22 at 17:23

2 Answers2

3

You can create an extension of view like this way. You can check out my blog entry for details.

import SwiftUI

extension View {
    /// CommonAppBar
    public func appBar(title: String, backButtonAction: @escaping() -> Void) -> some View {

        self
            .navigationTitle(title)
            .navigationBarTitleDisplayMode(.inline)
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: Button(action: {
                backButtonAction()
            }) {
                Image("ic-back") // set backbutton image here
                    .renderingMode(.template)
                    .foregroundColor(Colors.AppColors.GrayscaleGray2)
            })
    }
}

Now you can use this appBar in any place of the view.

struct TransactionsView: View {
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>

    var body: some View {
        VStack(spacing: 0) {

        }
        .appBar(title: "Atiar Talukdar") {
            self.mode.wrappedValue.dismiss()
        }
    }
}

struct TransactionsView_Previews: PreviewProvider {
    static var previews: some View {
        TransactionsView()
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Atiar Talukdar
  • 668
  • 11
  • 22
2

One way to achieve this is to use a custom view as an overlay.

For example, consider the below code which makes a custom navigation bar using an overlay:

struct Home: View {
    var body: some View {
        ScrollView {
            // Your Content
        }
        .overlay {
            ZStack {
                Color.clear
                    .background(.ultraThinMaterial)
                    .blur(radius: 10)

                Text("Navigation Bar")
                    .font(.largeTitle.weight(.bold))
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.leading, 20)
            }
            .frame(height: 70)
            .frame(maxHeight: .infinity, alignment: .top)
        }
    }
}

The ZStack inside the .overlay will make a view that looks like a navigation bar. You can then move it to its own struct view, add different variables to it and call it from the overlay.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
arata
  • 859
  • 1
  • 8
  • 23
  • Thanks @arata for response, Can we write some wrapper on Navigation view So we can take benefit of default Nav Bar functionality in some classes if required. – GrayFox Jan 25 '22 at 17:21
  • @GrayFox So, you want to modify the default navigation bar rather than making a new one from scratch? (This one is also a similar questions in a way) https://stackoverflow.com/questions/57686218/creating-baseview-class-in-swiftui – arata Jan 25 '22 at 17:23
  • Yes @arata, it would be better if we use existing Navigation bar rather than to create a new one. – GrayFox Jan 25 '22 at 17:27
  • Yes @arata, In that question[https://stackoverflow.com/questions/57686218/creating-baseview-class-in-swiftui] View Modifier is used to create a base view, But i wanna to reuse Navigation bar is same manner if possible. – GrayFox Jan 25 '22 at 17:30
  • 1
    @GrayFox interesting, never thought of it in that way. Maybe someone could answer your question. – arata Jan 25 '22 at 17:41