Petr Smejkal
Petr Smejkal

Reputation: 101

SwiftUI navigating to child view with searchable retracted causes out-of-bounds view, app unresponsive

I have a SwiftUI NavigationStack which goes 3 levels deep. In the level 2, I have a .searchable modifier. When pushing to level 3 while the search bar is retracted up (awaiting user to type) the level 3 view is out-of-bounds, CPU runs at 100% and app is unresponsive.

Level 2 to Level 3

This is the parent view (Level 1)

struct MainDatabaseView: View {
    @EnvironmentObject var routeManager: RouteManager

    var body: some View {
            Form {
                NavigationLink(value: Route.mainDatabasePilot) {
                    Button {
                        routeManager.databaseRoute.append(Route.mainDatabasePilot)
                    } label: {
                        DatabaseLabelLineView(icon: "person.2", primaryText: "Pilots", secondaryText: "Manage pilot profiles, remarks, and images. Use them for auto-complete.")
                    }
                }
              
            }
            .navigationDestination(for: Route.self, destination: { $0 })
            .navigationTitle("Database")
        
    }
}

This is Level 2 view with .searchable modifier.

struct MainTabPilotDatabaseView: View {
    @EnvironmentObject var pilotVM: PilotVM
    @EnvironmentObject var routeManager: RouteManager

    var body: some View {
        ZStack {
            listView()
            if pilotVM.pilotCollection.isEmpty {
                EmptyDataView(primaryText: "No Pilots Yet", secondaryText: "You can add pilots into database here. When importing existing logbooks, pilots will be automatically migrated", image: .emptyDatabase)
            }
        }
    }

    @ViewBuilder
    func listView() -> some View {
        List {
            ForEach(pilotVM.filteredPilots, id: \.id) { pilot in

                NavigationLink(value: Route.pilot(pilot: pilot)) {
                    PilotCell(pilot: pilot, isInDetailView: false) {}
                        .contentShape(Rectangle())
                        .swipeActions(edge: .trailing) { delete(for: pilot) }
                        .swipeActions(edge: .leading) { markFavorite(for: pilot) }
                }
            }
        }
        .searchable(text: $pilotVM.searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "Name, Base, Airline, Remarks")
        .overlay {
            if pilotVM.filteredPilots.isEmpty && !pilotVM.pilotCollection.isEmpty && !pilotVM.searchText.isEmpty {
                if #available(iOS 17.0, *) {
                    ContentUnavailableView.search(text: pilotVM.searchText)
                }
            }
        }
        .onAppear { pilotVM.fetchPilots() }
        .onDisappear { pilotVM.searchText = "" }
        .autocorrectionDisabled()
        .navigationTitle("Pilot Database")
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) { addPilot() }
        }
    }
}

In level 3, I have a simple Form.

I have tried to comment out everything in level 3 and level 2. The behaviour stops when the .searchable is commented out. I am wondering what I am missing.

This is the stack trace

Stack Trace 1 Stack Trace 2

Upvotes: 0

Views: 52

Answers (1)

Petr Smejkal
Petr Smejkal

Reputation: 101

I have found a fix, adding .navigationBarTitleDisplayMode(.inline) to the parent view (level 2) has fixed the issue.

Upvotes: 0

Related Questions