'SwiftUI Modal Inherits SearchBar during Sheet Presentation

Consider the following example with a list and a button wrapped in a HStack that opens up a sheet:

struct ContentView: View {

    @State var text: String = ""
    @State var showSheet = false

    var body: some View {
        NavigationView {
            List {
                HStack {
                    button
                }
                Text("Hello World")
            }
            .searchable(text: $text)
        }
    }

    var button: some View {
        Button("Press", action: { showSheet = true })
            .sheet(isPresented: $showSheet) {
                modalView
            }
    }

    var modalView: some View {
        NavigationView {
            List {
                Text("Test")
            }
        }
    }
}

On press of the button, a modal is presented to the user. However, the searchable modifier gets passed to the modal, see this video.

Now if the HStack is removed, everything works fine:

List {
    button
    Text("Hello World")
}

In addition, everything works also fine if the modal is not a NavigationView:

var modalView: some View {
    List {
        Text("Test")
    }
}

Does somebody know what the problem here might be or is it once again one of those weird SwiftUI bugs?



Solution 1:[1]

putting the sheet, outside of the button and the List, works for me. I think .sheet is not meant to be inside a List, especially where searchable is operating.

struct ContentView: View {
    
    @State var text: String = ""
    @State var showSheet = false
    
    var body: some View {
        NavigationView {
            List {
                HStack {
                    button
                }
                Text("Hello World")
            }
            .searchable(text: $text)
        }
        .sheet(isPresented: $showSheet) {
            modalView
        }
    }
    
    var button: some View {
        Button("Press", action: { showSheet = true })
    }
    
    var modalView: some View {
        NavigationView {
            List {
                Text("Test")
            }
        }
    }
}

Solution 2:[2]

Another workaround is to use navigationBarHidden = true, but then you must live without the navigation bar in the sheet view.

var modalView: some View {
    NavigationView {
        List {
            Text("Test")
        }
        .navigationBarHidden(true)
    }
}

Btw, on iPadOS it helps to use .searchable(text: $text, placement: .sidebar)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 workingdog support Ukraine
Solution 2 Hendrik