Create common layout for Navigation Bar in SwiftUI So other SwiftUI views should reuse same Nav Bar

Viewed 995

In iOS SwiftUI, How we can make a common layout for Navigation Bar. So we can use that in all project without re-write the same code.

enter image description here

We can use ViewBuilder to create 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 we can add Navigation bar Code in View Builder or Base view?

2 Answers

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 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 overlay.

You can create an extension of view like this way. You can checkout this article 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()
    }
}
Related