ScoobyDooku
ScoobyDooku

Reputation: 225

My build fails when putting a Menu in ToolbarItem

I'm using a NavigationStack for an app view with three ToolbarItems. The last one is supposed to be a straight forward options menu:

NavigationStack {
    // CONTENT
    .toolbar {
        ToolbarItem(placement: .topBarTrailing) {
            Menu {
                Button {
                    // Request update
                } label: {
                    Label("Sync now", systemImage: "arrow.triangle.2.ciclepath")
                }
                // More buttons/options
            } label: {
                Label("Options", systemImage: "ellipsis")
            }
        }
    }
}

I see nothing wrong with those lines of code and yet as soon as I use Menu I get the error Static method 'buildExpression' requires that 'ToolbarItem<(), some View>' conform to 'View' on the other ToolbarItems.

I should add that I have tried this in Playgrounds and that works just like expected. No errors there. If I change the placement to .secondaryAction and remove the Menu, my Button(s) get listed but without the label icon. This is not an option for me because I want to use a Menu with Sections, the ellipsis icon in the Toolbar etc. Only when I use Menu do I get the error. Any ideas what causes this? Anyone experienced something similar?

Edit: There should not be too many subviews in the same body view. The overflow Menu in question will eventually contain maybe 6 items or so. The error is there even with only one button anyways. Here's my complete body (stripped of irrelevant modifiers) [pun intended]:

var body: some View {
    NavigationStack {
        if selectedView == "Week" {
            Text("Week view")
        }
        if selectedView == "Month" {
            Text("Month view")
        }
        ScrollViewReader { scrollView in
            ScrollView {
                ListView()
            }
            // Go to today button overlay
            .overlay(alignment: .bottomTrailing) {
                Button {
                    scrollView.scrollTo(goToDate, anchor: .top)
                } label: {
                    Text("Go to today")
                }
            }
        }
        // NAVIGATION TOOLBAR
        .navigationTitle("Title") // Won't show because of principal ToolbarItem below
        .navigationBarTitleDisplayMode(.inline)
        // TOP TOOLBAR
        .toolbar {
            // Title
            ToolbarItem(placement: .principal) {
                VStack {
                    Text("Title") // Actual title!
                        .font(.headline)
                    if syncTime != "a moment ago" {
                        HStack(spacing: 3) {
                            Text("Last sync:")
                            Text(syncTime)
                        }
                    } else {
                        Text("Up to date")
                    }
                }
            }
            // Profile image -> Settings sheet
            ToolbarItem(placement: .topBarLeading) {
                Button(action: {
                    showProfileSheet.toggle()
                }) {
                    Image("profile")
                }
                .sheet(isPresented: $showProfileSheet) {
                    ProfileModal(isPresented: $showProfileSheet)
                        .presentationDetents([.medium, .large])
                        .presentationDragIndicator(.hidden)
                }
            }
            // Export sheet
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    showExportSheet.toggle()
                } label: {
                    Image(systemName: "square.and.arrow.up")
                }
                .sheet(isPresented: $showExportSheet) {
                    ExportModal(isPresented: $showExportSheet)
                        .presentationDetents([.medium, .large])
                }
            }
            /*ToolbarItem(placement: .topBarTrailing) {
                Menu {
                    Button {
                        // Request update action
                    } label: {
                        Label("Sync now", systemImage: "arrow.triangle.2.ciclepath")
                    }
                    // More buttons/options
                } label: {
                    Label("Options", systemImage: "ellipsis")
                }
            }*/
        }
    }
}

The last ToolbarItem that I've commented out is the one causing the error. If I remove only the Menu but keep the button, there is no error. It literally is the Menu that causes this. I don't understand!

Upvotes: 0

Views: 254

Answers (1)

Connor Nguyen
Connor Nguyen

Reputation: 1

Try putting them in ToolBarItemGroup and get rid of ToolbarItem, it works for me.

Upvotes: 0

Related Questions