SwiftUI - Placing ToolbarItem on .keyboard does not work

I have a regular SwiftUI View embedded inside of a NavigationStack. In this view, I make use of the .searchable() view modifier to make that view searchable. I have a button on the toolbar placed on the .confirmationAction section, which is a problem when a User types into the search bar and the button gets replaced by the SearchBar's cancel button. Thus, I conditionally place the button, depending on whether a User is searching, either on the navigationBar or on the keyboard. The latter does not work however, as the button does not show and when trying to debug the View Hierarchy, Xcode throws an error saying the View Hierarchy could not be displayed. If I set the button to be on the .bottomBar instead, it shows up perfectly and the View Hierarchy also displays with no further issue. Has someone come across this issue and if so, how did you get it fixed? Thank you in advance.

I have a similar issue and haven't found any solution yet. It is obviously a problem with iOS 17 because on iOS 16 it used to work as expected.

Can either of you post some sample code to show the problem? I tested on iOS 17 and iOS 16.4 with this code and saw the same behavior of the keyboard button only showing up for the TextField and not in .searchable, but am unsure if I am replicating it correctly. Either way, this is definitely worth a feedback report (at https://feedbackassistant.apple.com) and please post the FB number here! If you can attach a small sample project to the feedback report, that would help a lot. Thank you!

This is the code I tested with:

struct ContentView: View {
    @State private var text: String = ""
    @State private var searchText: String = ""
    var body: some View {
        NavigationStack {
            TextField("Test TextField", text: $text)
                .toolbar {
                    ToolbarItem(placement: .keyboard) {
                        Button("TestButton") {
                            //code
                        }
                    }
                }
        }
        .searchable(text: $searchText)
    }
}

I have a sample project showing the missing toolbar items on .keyboard placement:

https://github.com/MortenGregersen/KeyboardBarTest

It also contains a video showing the issue.

The issue is also present in apps in the App Store build with Xcode 14.

I have submitted a feedback with all the details: FB13209435

Similar thing is happening in a project im running, but simulator is working fine but on device isnt which is really strange as there the same devices and same software version

I have the same problem. Simulator works as expected and the keyboard button shows, but when I test the build on a device it isn't visible.

If the toolBar is placed in a view that's inside a NavigationStack it doesn't work and this is a bug.

Thanks for all of your responses, this is a known issue with no supported workaround. Please keep filing feedback reports if you have not already, thank you!

There is a workaround! The solution may not for work for everyone but at least it is worth a try. I had to show (and hide) a sheet right after entring the view. Miraculously the toolbar starts to appear after that. Be advised that this code requires iOS 16.4 and above. If you remove .presentationBackground(.clear) it is available for lower targets.

struct YourView: View {
    @State var isShowingAWorkAround = true

     var body: some View{
         HSTack {
         // you code here
         }
         .sheet(isPresented: $isShowingWorkAround) {
             TemporarySheet {
                  self.isShowingAufmass = false
              } resetCallback: {
                  self.isShowingWorkAround = false
              }.presentationBackground(.clear)
           }
      }
}

Code for TemporarySheet

struct TemporarySheet: View {
    let dismissCallback: (() -> Void)
    let resetCallback: (() -> Void)
    var body: some View {
        Text("").onAppear {
            self.dismissCallback()
        }.onDisappear {
            self.resetCallback()
        }
    }
}

Sure you can take anything instead Text("").

Tested on iOS 17.2 public beta (which has identical problem as 17.1).

I have the same issue on iOS 17. The ToolbarItem works on a physical device when debugging through Xcode, but does not work on the physical device.

I have the same issue (IOS 17).

Experiencing the same issue. Toolbar works fine in simulator, but does not show up on physical device. However, if I open the view, move the app to the background and then move it back to the foreground again, the toolbar suddenly works as expected.

Is your button in an HStack with a Spacer? I used .frame(maxWidth: .infinity, alignment: .trailing) instead and it showed for me.

It's been couple months already and still there is no solution to this problem? Unbelievable!

same problem here

The problem still exists. It seems that the toolbar becomes visible after the first submit.

I am also seeing a variety of this problem - the toolbar appears, but there's no content in the toolbar. Code is below but the TL;DR is the same as F99's response above, removing the Spacer() from the HStack fixes the problem

            HStack {
                TextField(store.prompt, text: $input)
                    .hideableToolbar(show: store.showToolbar) {
                        ToolbarItemGroup(placement: .keyboard) {
                            HStack {
                                ForEach(fastList) { item in
                                    Button {
                                        //
                                    } label: {
                                        Text("\(item.name)")
                                    }
                                }
                                Spacer()  // <–– COMMENTING OUT THIS LINE FIXES THE PROBLEM
                            }
                        }
                    }
                }
            }
SwiftUI - Placing ToolbarItem on .keyboard does not work
 
 
Q