Reputation: 43
I have a largish app with a deep navigation stack. I display a list of items and filter with .searchable. When an item is selected using a search I get the following messages:
List failed to visit cell content, returning an empty cell. - SwiftUI/UICollectionViewListCoordinator.swift:367 - please file a bug report.
List failed to visit cell content, returning an empty cell. - SwiftUI/UICollectionViewListCoordinator.swift:367 - please file a bug report.
Someone is removing an active search controller while its search bar is visible. The UI probably looks terrible. Search controller being removed: <SwiftUI.SwiftUISearchController: 0x12c00d800> from navigation item: <UINavigationItem: 0x12d111fd0> style=navigator leftItemsSupplementBackButton
The third message is a warning. The first two are not. Prior to learning and adding dismissSearch() to the code below, I did not get the please file a bug report messages, only the "Someone is removing..." warning.
I have put together a small app that mimics the architecture and reproduces the problem.
If you run the following app, touch "Select something", enter a letter (e.g. k) and then select a row, the warning is displayed.
I am using Xcode Version 15.0.1 (15A507) and running on either an iPhone 15 Simulator iOS 17.0 or a real device (14 pro) on iOS 17.
import SwiftUI
struct ContentView: View {
@StateObject private var dataService = DataService()
var body: some View {
NavigationStack(path: $dataService.path) {
Form {
Text("\(dataService.selectedItem ?? "Nothing") selected")
NavigationLink(value: 1) {
Text("Select something")
}
}
.navigationDestination(for: Int.self) { value in
ListView()
.environmentObject(dataService)
.searchable(text: $dataService.searchText, placement: .navigationBarDrawer(displayMode: .always))
}
}
}
}
struct ListView: View {
@Environment(\.dismissSearch) private var dismissSearch
@EnvironmentObject private var dataService: DataService
var body: some View {
List(dataService.filteredOptions, id: \.self) { option in
Button( action: {
dataService.selectedItem = option
dismissSearch()
dataService.path.removeLast()
}) {
Text(option)
}
}
}
}
class DataService: ObservableObject {
@Published var path = Array<Int>()
@Published var selectedItem: String?
@Published var searchText: String = ""
var filteredOptions: [String] {
if searchText.isEmpty {
return DataService.names
} else {
return DataService.names.filter { name in
name.localizedCaseInsensitiveContains(searchText)
}
}
}
static let names = [
"Mark",
"David",
"John",
"Pick"
]
}
I have tried reordering the button actions. No change. I have tried putting the actions in a Task. No change.
I have tried using dismiss()
instead of dataService.path.removeLast()
. When I do this the warning disappears but the app becomes unresponsive after the ListView is dismissed.
If I use dismiss without dismissSearch I get the following warning. > Inconsistent state handled when removing old search controller. Investigate if repro steps are available. Otherwise, ignore.
In any case, in my app, I sometimes need to pop several views off the stack, so I need to remove items from the end of the path. I have searched for other references to this but couldn't find the solution.
Upvotes: 2
Views: 424