Home > Enterprise >  Multiple NavigationViews in SwiftUI - How to get rid of multiple toolbar items (i.e the back-button
Multiple NavigationViews in SwiftUI - How to get rid of multiple toolbar items (i.e the back-button

Time:01-15

I am making an app where the first view the users see is a home screen with buttons that takes them to a second view. One of the second views present the user with a list of items. When the user clicks on one of these items the user comes to a detailed view of the item. When the user comes to the detailed view he is unfortunately presented with two toolbar buttons in the corner as can be seen here:

toolbar buttons.

I know that one of the solutions is to only have one navigationview and that solves my problem. But I need to have toolbar items in my listview to be able to add more items, sort the list and have the list searchable which I'm not able to do without navigationView. I Have tried using scrollView and NavigationStack but it comes out blank.

Does anyone have an idea how to work with mulitple views, not getting double up "back buttons" on the toolbar and still have other toolbar items?

View one: (Home Screen):

NavigationView {
            ZStack {
                VStack {
                    Text(title)
                        .font(.custom("Glacial Indifference", size: 34, relativeTo: .headline).weight(.bold))
                        .multilineTextAlignment(.leading)
                        .foregroundColor(.white)
                        .tracking(10)
                        .padding(8)
                        .background(
                            Rectangle()
                                .fill(.gray)
                                .frame(width: 1000, height: 150)
                                .ignoresSafeArea()
                                .opacity(0.5))
                    Spacer()
                }
                VStack {
                    NavigationLink {
                        MapView()
                    } label: {
                        Buttons(str: "Cheese Map")
                    }
                    .padding(.bottom, 200)
                }
                VStack {
                    NavigationLink {
                        TabView()
                    } label: {
                        Buttons(str: "Cheese List")
                    }
                    .padding(.bottom, 400)
                }

Second View (list):

NavigationView {
            List {
                ForEach(items, id: \.id) { item in
                    NavigationLink {
                        ItemView(item: item)
                    } label: {
                        ListItem(item: item)
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button {
                        showingAddItem = true
                    } label: {
                        Image(systemName: "plus")
                        Text("Add Item")
                            .font(.footnote)
                            .italic()
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Menu("Sort") {
                        Picker("Filter Options", selection: $selectedSort) {
                            ForEach(sortOptions, id: \.self) {
                                value in
                                Text(value)
                                    .tag(value)
                            }
                        }
                    }
                    .onChange(of: selectedSort) { _ in
                        let sortBy = sorts[sortOptions.firstIndex(of: selectedSort)!]
                        items.sortDescriptors = sortBy.descriptors
                    }
                }
            }
            .sheet(isPresented: $showingAddItems) {
                AddItemsView(items: Items())
            }
            .navigationTitle("Item List")
            
            .searchable(text: $searchText)
        }
    }
}

DetailView:

ScrollView {
            ZStack {
                VStack {

//More code...

CodePudding user response:

Both .toolbar and .searchable find the nearest enclosing NavigationView automatically. You do not need a NavigationView in your list view.

Here's a self-contained demo. It looks like this:

Demo of pushing a view that uses the toolbar and searchable modifiers.

Here's the code:

import SwiftUI
import PlaygroundSupport

struct HomeScreen: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Cheese Map") { Text("Map") }
                NavigationLink("Cheese List") { ListView() }
            }
            .navigationTitle("Home Screen")
        }
        .navigationViewStyle(.stack)
    }
}

struct ListView: View {
    @State var items = ["Cheddar", "Swiss", "Edam"]
    @State var search: String = ""

    var filteredItems: [String] {
        return items.filter {
            search.isEmpty
            || $0.localizedCaseInsensitiveContains(search)
        }
    }

    var body: some View {
        List(filteredItems, id: \.self) {
            Text($0)
        }
        .searchable(text: $search)
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Button {
                    withAnimation {
                        items.append("Gouda")
                    }
                } label: {
                    Label("Add Item", systemImage: "plus")
                }
                .disabled(items.contains("Gouda"))
            }
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Menu("Sort") {
                    Button("Ascending") {
                        withAnimation {
                            items.sort()
                        }
                    }
                    Button("Descending") {
                        withAnimation {
                            items.sort()
                            items.reverse()
                        }
                    }
                }
            }
        }
        .navigationTitle("Cheese List")
    }
}

PlaygroundPage.current.setLiveView(HomeScreen())
  • Related