.toolbar modifier positions buttons at the bottom of the view

Following the coding intro to SwiftUI a curiosity arose with regard to the toolbar placement in the view.

The first question is regarding the use of the toolbar modifier. The demo showed the buttons appearing at the top of the view, but they appear at the bottom of the view in my rendition, despite applying the modifiers to different blocks within the body calculated property. Any ideas as to why this would be would be appreciated.

Additionally, the question begs as to whether the .navigationBarItems modifier is to be replaced by the new toolbar modifier? Or, will it simply be added to the toolset?


Code Block
    var body: some View {
        NavigationView {
            List {
                ForEach(store.sandwiches) { sandwich in
                    SandwichCell(sandwich: sandwich)
                }
                .onMove(perform: moveSandwiches)
                .onDelete(perform: deleteSandwiches)
                
                HStack {
                    Spacer()
                    Text("\(store.sandwiches.count) Sandwiches")
                        .foregroundColor(.secondary)
                    Spacer()
                }
            }
            .navigationTitle("Sandwiches")
            .toolbar {
                #if os(iOS)
                EditButton()
                #endif
                Button("Add", action: makeSandwich)
            }
            
            Text("Select a sandwich")
                .font(.largeTitle)
        }
    }


Accepted Reply

You can wrap your button in a ToolbarItem, and explicitly specify the placement, like this:

Code Block
.toolbar {
ToolbarItem(placement: ToolbarItemPlacement.navigationBarTrailing) {
Button("Add", action: makeSandwich)
}
}


You can see all of the values of the ToolbarItemPlacement in the documentation.

As for .navigationBarItems, I'm pretty sure this modifier is not supported on macOS natively, only if you make a Catalyst app. If you want a cross-platform view, you should rather opt for .toolbar.

Replies

You can wrap your button in a ToolbarItem, and explicitly specify the placement, like this:

Code Block
.toolbar {
ToolbarItem(placement: ToolbarItemPlacement.navigationBarTrailing) {
Button("Add", action: makeSandwich)
}
}


You can see all of the values of the ToolbarItemPlacement in the documentation.

As for .navigationBarItems, I'm pretty sure this modifier is not supported on macOS natively, only if you make a Catalyst app. If you want a cross-platform view, you should rather opt for .toolbar.
Thank you for replying.

Yes, the following code does indeed work.

Code Block language
            .toolbar {
                #if os(iOS)
                ToolbarItem(placement: ToolbarItemPlacement.navigationBarLeading) {
                    EditButton()
                }
                #endif
                ToolbarItem(placement: ToolbarItemPlacement.navigationBarTrailing) {
                    Button("Add", action: makeSandwich)
                }
            }


The demo was presented without the ToolbarItem wrappers and the demo worked beautifully and with the iOS qualifiers as well.

The documentation link is very welcome.

You are right to mention the cross platform facet as the demo is billed as a cross platform app and I was probably panicking a little over my beloved .navigationBarItems modifier.

The code using explicit ToolbarItemPlacement puts the controls in the right place at first, but after tapping on the Add button, the Edit button disappears. This only happens when placing it using .navigationBarLeading, not when placing it with .navigationBarTrailing. Any ideas on how to address this?
Re: Edit button disappears when Add button is used, never re-appears

I've verified this in my setup as well (Catalina, Xcode 12.0 beta 12A6159). If both buttons are put as "trailing", it doesn't happen. If *either* button is set as "leading", it does happen. Happens in swiftUI preview and when app is run on simulator device.

I submitted it as a feedback item, but will help if others report as well.
  • -

Re: buttons initially appear as buttons in a bottom-of-screen-toolbar when not added with specific Placement parameters

I see this as well, and adding specific Placement fixes the behavior to match what is shown in video.

So clearly version of SwiftUI framework and Xcode shown in video are not what shipped as Beta 1 to developers.

I also verify that when tapping the Add button the Edit button disappears, regardless of whether the buttons are within the #if os(iOS) block or not.

It does suggest a disparity between the demo and reality.
Xcode 12 beta 2 now "acknowledges" the Edit button in the above code as a tool bar item (at the top of the view) but persists to render the Add button at the bottom of the view. Whether the two buttons are located within the #if block or note, matters not a jot. Furthermore, all buttons remain in view despite tapping on either one.

This is progress in the correct direction.
Xcode 12 beta 2 has also fixed the issue with the disappearing button. If the ToolbarItem wraps the button, they can be position in their expected positions and remain in place despite tapping either button. Now, all that remains to be fixed is the "normal" toolbar implementation. Both buttons can be placed within the #if block if desired without affecting functionality.

Code Block SwiftUI
            .toolbar {
                #if os(iOS)
                ToolbarItem(placement: ToolbarItemPlacement.navigationBarLeading) {
                    EditButton()
                }
                #endif
                ToolbarItem(placement: ToolbarItemPlacement.navigationBarTrailing) {
                    Button("Add", action: makeSandwich)
                }
            }