SwiftUI: Keyboard toolbar item not working in iOS 17.4

It seems like this may have been an issue for a while based on what I've seen, but I have added a toolbar item to a textfield keyboard and it doesn't show. The only way I can get it to show is by opening the keyboard, typing something, closing the keyboard, and then reopening it. Anyone have a workaround for this? It's like Apple purposely wants to make it difficult to close the keyboard.

TextField("Something here...", text: $text, axis: .vertical)
                        .multilineTextAlignment(.leading)
                        .toolbar {
                            ToolbarItemGroup(placement: .keyboard, content: {
                                Button("Close") { }
                            })
                        }

Issue

In SwiftUI, the keyboard toolbar often does not appear on the first focus when using .toolbar. It only appears after switching fields or minimizing the app.

Solution

To force UI re-rendering, we use a hidden Toggle that switches states when the view appears, ensuring that SwiftUI updates and correctly displays the toolbar.

    // Hidden toggle for UI refresh
    @State private var toggleState = false
    // .......
    // Hidden toggle forces UI update
        Toggle("", isOn: $toggleState)
            .labelsHidden()
            .hidden()
    // ......
    
        .onAppear {
            toggleState.toggle() // Trigger UI update
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                toggleState.toggle() // Toggle back after a delay
            }
        }
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                    Button("Done") { /*...*/ } // Close keyboard
            }
        }
   //

Sory, here is a full example


struct ContentView: View {
    @State private var name = ""
    @State private var email = ""
    @State private var toggleState = false
    @FocusState private var focusedField: Field?

    enum Field { case name, email }

    var body: some View {
        VStack {
            
            VStack(alignment: .leading) {
                Text("Name")
                TextField("Enter your name", text: $name)
                    .focused($focusedField, equals: .name)
                    .textFieldStyle(RoundedBorderTextFieldStyle())

                Text("Email")
                TextField("Enter your email", text: $email)
                    .focused($focusedField, equals: .email)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .textContentType(.emailAddress)
            }
            .padding()

            
            Toggle("", isOn: $toggleState)
                .labelsHidden()
                .hidden()
        }
        .padding()
        .onAppear {
            toggleState.toggle()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                toggleState.toggle()
            }
        }
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                Button {
                    focusedField = nil
                } label: {
                    Image(systemName: "keyboard.chevron.compact.down")
                }

                Spacer()
                Button("Clear") {
                    name = ""
                    email = ""
                }

                Spacer()
                Button("Next") {
                    switch focusedField {
                    case .name:
                        focusedField = .email
                    case .email:
                        focusedField = nil
                    default:
                        break
                    }
                }
            }
        }
    }
}
SwiftUI: Keyboard toolbar item not working in iOS 17.4
 
 
Q