Persistent Toolbar in SwiftUI

238 Views Asked by At

I was wondering if there is a way to make a persistent toolbar in SwiftUI? I have found some examples of people making toolbars have dynamic elements, but I haven't found a good solution for a toolbar that is persistent across multiple pages/views.

Clearly I could just choose to copy/paste all of my ".toolbar" code for every NavigationView page, but that seems a bit inefficient.

Thoughts?

P.S. Is there a way to add a drop shadow to the toolbar? Haven't found anything helpful online...

I currently have the following code:

.toolbar
    {
        ToolbarItem (placement: .principal) {
            PersistentToolbar()
        }
    }

/*
----------------------------------------------------------
Where PersistentToolbar() is defined (in another file) as:
----------------------------------------------------------
*/

struct PersistentToolbar: View {
    
    var body: some View {
        
        HStack {
            Image(systemName: "line.3.horizontal")
                .foregroundColor(.black)
            
            Spacer()
            
            Button(action: {
                print("Go Home")
            }, label: {
                Image("Logo")
                    .resizable()
                    .frame(width: 40, height: 40)
            })
            
            Spacer()
            
            Button {
                print("Profile Page")
            } label: {
                NavigationLink(destination: ProfileView()) {    // I want to navigate to a "ProfilePage" when the user taps the profile icon
                    Image(systemName: "person.crop.circle")
                }
                .foregroundColor(.black)
            }
        }
    }
}

1

There are 1 best solutions below

0
GoZoner On

Define a 'wrapper view' that adds your toolbar to every 'wrapped view'

struct WrappedToolbarView <Root> : View where Root : View {
    var root: () -> Root

    var body: some View {
        root()
           .toolbar {
               ToolbarItem (placement: .principal) {
                  PersistentToolbar()
               }
           }
    }
}

Now, whenever you navigate to another view (via NavigationLink or .navigationDestination) you use WrappedToolbarView.

struct DetailView: View {
   var body: some View {
       WrappedToolbarView {
           Text ("some details")
       }
   }
}