Understanding .ignoresSafeArea(.keyboard)

I'm struggling to figure out how to use .ignoresSafeArea(.keyboard). The documentation isn't very thorough and so I've been experimenting to figure out how it works.

I've come across an issue with Menu that's shown by the sample code below. Its layout approximates a view in my app. You'll need to run it on the iPhone SE (1st generation), although I imagine it'll work on all of the older, squatter screened devices since the keyboard will reach the ellipsis button.

If you tap the magnifying glass button to display a sheet, then tap in the search field to show the keyboard and then swipe the sheet away it causes the layout to be changed. If you swipe the sheet all the way to below the keyboard you can see the ellipsis button has been pushed up to avoid the keyboard. Tapping on the ellipsis button readjusts to the correct layout. If I change the ellipsis button to an image, by removing the Menu surrounding it, then the layout is unaffected.

Debug View Hierarchy nicely shows how the button has adjusted to the keyboard. (I've done the steps above before swiping the sheet away, using Debug View Hierarchy and hidden the sheet.) The two images show the layout when using a Menu and Image respectively.

Am I using .ignoresSafeArea(.keyboard) incorrectly? I'm surprised that a keyboard in a sheet is affecting the views behind it and that the modifier doesn't seem to apply to the Menu.

Is this a bug? Is there a workaround?

Thanks

struct ContentView: View {
    @State var showSheet = false
    @State var text = ""
    
    var body: some View {
        VStack(spacing: 0) {
            Image(systemName: "square.fill")
                .resizable()
                .aspectRatio(1, contentMode: .fit)
                .padding(.bottom, 4)
            
            HStack {
                VStack(alignment: .leading) {
                    Text("headline").font(.headline)
                    Text("subheadline").font(.subheadline)
                }
                
                Spacer()
                
                Menu {
                    Button("Action 1") {}
                } label: {
                    Image(systemName: "ellipsis.circle.fill")
                        .contentShape(Rectangle())
                        .frame(width: 44, height: 44, alignment: .trailing)
                }
            }
            .padding(.horizontal)
            
            Spacer()
            
            HStack {
                Image(systemName: "square.fill")
                    .frame(width: 44, height: 44)
            }
            
            Spacer()
            
            HStack {
                Image(systemName: "square.fill")
                    .frame(width: 44, height: 44)
            }
        
            Spacer()
            
            HStack {
                Button(action: { showSheet = true }) {
                    Image(systemName: "magnifyingglass")
                        .contentShape(Rectangle())
                        .frame(width: 44, height: 44)
                        .font(.system(size: 24))
                }
                .sheet(isPresented: $showSheet) {
                    NavigationView {
                        VStack {
                            TextField("Placeholder", text: $text)
                                .textFieldStyle(RoundedBorderTextFieldStyle())
                                .frame(height: 44)
                                .padding([.horizontal, .top])
                            
                            List {
                                
                            }
                        }
                        .navigationBarTitle(Text("Search"), displayMode: .inline)
                    }
                }
            }
        }
        .padding(.bottom, 4)
        .ignoresSafeArea(.keyboard)
    }
}
Terms of Service

Privacy Policy

Cookie Policy