SwiftUI 3.0中NavigationLink搭配.searchable修饰器无法正常工作问题
问题原因
你遇到的搜索结果条目NavigationLink跳转失效问题,是searchCompletion修饰器的事件优先级高于NavigationLink点击事件导致的:当你给搜索建议条目添加searchCompletion修饰器后,点击条目会优先触发系统默认的文本补全逻辑,自动将补全内容填入搜索框、收起搜索建议列表,NavigationLink的跳转事件会被直接拦截,无法触发。
解决方案
根据你的需求可以选择以下两种修改方案:
方案1:无需搜索补全功能,直接删除searchCompletion修饰器
如果你不需要点击搜索建议自动填充搜索框的功能,直接删掉搜索建议部分NavigationLink末尾的.searchCompletion(item.label)代码即可,修改后搜索建议部分代码如下:
// Search bar .searchable(text: $searchedText, placement: .automatic) { if !searchedText.isEmpty { // Search result ForEach($items.filter({$0.label.wrappedValue.contains(searchedText)})) { $item in NavigationLink(destination: ItemView(item: $item)) { HStack { if(item.value) { Image(systemName: "star.fill").foregroundColor(.yellow) } Text(item.label) } } // 删掉原来的.searchCompletion(item.label)即可 } } }
方案2:需要保留搜索补全功能,重构搜索逻辑
如果你需要保留点击搜索建议自动补全搜索词的功能,可以将搜索过滤逻辑迁移到List的数据源上,不需要在searchable的建议闭包中声明NavigationLink,修改后的完整代码如下:
struct OrderItem : Identifiable { let id = UUID() var label : String var value : Bool = false } struct BindingTest: View { @State var items = [OrderItem(label: "Shirts"), OrderItem(label: "Pants"), OrderItem(label: "Socks")] @State private var searchedText = "" // 过滤后的列表数据源 var filteredItems: [OrderItem] { if searchedText.isEmpty { return items } else { return items.filter { $0.label.contains(searchedText) } } } var body: some View { NavigationView { // 直接使用过滤后的数据源渲染列表 List($filteredItems) { $item in NavigationLink(destination: ItemView(item: $item)) { HStack { if(item.value) { Image(systemName: "star.fill").foregroundColor(.yellow) } Text(item.label) } } } .navigationBarTitle("Clothing") // Search bar .searchable(text: $searchedText, placement: .automatic) { if !searchedText.isEmpty { // 搜索建议只保留带searchCompletion的文本,点击自动补全搜索词 ForEach(filteredItems) { item in Text(item.label) .searchCompletion(item.label) } } } } } }
修改后点击搜索建议会自动补全搜索词、刷新列表为过滤后的结果,点击列表条目即可正常跳转。
内容的提问来源于stack exchange,提问作者Alessio Rubicini
相关产品推荐
相关产品推荐

