Search code examples
swiftuiswiftui-navigationviewswiftui-navigationstack

Navigation bug when dismissing view while focussing on empty .searchable() modifier


When trying to navigate back from a view using the environment Dismiss value while also focussing on an empty searchable modifier the view you navigated back to becomes unresponsive. This is due to an empty UIView blocking any interaction with the view as seen in this screenshot:

Empty UIView blocking view after navigating back

Empty UIView blocking view after navigating back

This only occurs when the searchbar is focussed and empty when trying to navigate back. When there's a value in the searchbar everything works:

GIF of the bug

GIF of the bug

Am I doing something wrong here?

Tested on Xcode 14.2 iPhone 14 Pro (iOS 16.0) simulator.

import SwiftUI

struct MainPage: View {
    var body: some View {
        if #available(iOS 16.0, *) {
            NavigationStack {
                Text("Main view")
                NavigationLink(destination: DetailView()) {
                    Text("Click me")
                }
            }
        }
    }
}

struct DetailView: View {
    @Environment(\.dismiss) private var dismiss
    @State private var searchText = ""
    
    var body: some View {
        VStack {
            Text("Detail view")
            Button("Go back") {
                dismiss()
            }
        }
        .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
    }
}

This bug only seems to happen when using NavigationStack or NavigationView with a .navigationViewStyle(.stack). When using NavigationView without a navigationViewStyle it seems to work fine. Currently I can work around this using the latter but I would prefer to use NavigationStack as NavigationView has become deprecated since iOS 16.0.

Any help is appreciated.


Solution

  • I made a bug report to apple but I have yet to receive an answer from them.

    For now I worked around this by setting my searchText binding to a space " " which seems to make this work.

    import SwiftUI
    
    struct MainPage: View {
        var body: some View {
            if #available(iOS 16.0, *) {
                NavigationStack {
                    Text("Main view")
                    NavigationLink(destination: DetailView()) {
                        Text("Click me")
                    }
                }
            }
        }
    }
    
    struct DetailView: View {
        @Environment(\.dismiss) private var dismiss
        @State private var searchText = ""
        
        var body: some View {
            VStack {
                Text("Detail view")
                Button("Go back") {
                    // Setting the searchtext to anything else but an empty string makes this work
                    searchText = " " // <---
                    dismiss()
                }
            }
            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
        }
    }