SwiftUI中实现可搜索文本并跳转带搜索文本新视图的问题排查
问题描述
我正在开发一款提供选择功能的SwiftUI应用,用户选择颜色后会跳转至新视图,视图内容由文本参数决定。我希望通过SwiftUI搜索栏实现该功能:用户输入时显示可选选项。但当前代码存在问题:无论选择什么内容,仅显示选中项,且底部的“Go”按钮始终不可用(呈灰色文本状态)。
当前代码
struct ContentView: View { let colors = ["Blue", "Cyan", "Teal", "Mint", "Green", "Yellow", "Orange", "Red", "Pink", "Purple", "Indigo"] var filteredColors: [String] { // 1 if queryString.isEmpty { return colors } else { return colors.filter { $0.localizedCaseInsensitiveContains(queryString) } } } @State private var queryString = "" @State private var goToSecondView = false var body: some View { NavigationView { List(filteredColors, id: \.self) { color in Text(color) } .navigationTitle("Colors") .searchable(text: $queryString, prompt: "Color Search", suggestions: { ForEach(colors.filter { $0.localizedCaseInsensitiveContains(queryString) } , id: \.self) { suggestion in Text(suggestion) .searchCompletion(suggestion) } }) .onSubmit(of: .search) { // 1 print("submit") goToSecondView = true } } NavigationLink { if goToSecondView { SecondView(querystring: queryString) } } label: { Text("Go") } } } struct SecondView : View { var querystring : String var body : some View { Text(querystring) } }
问题分析与修复方案
核心问题点
选中后列表仅显示单项:
当前用queryString同时承担搜索输入和选中值的角色,导致过滤后的列表始终只匹配queryString的内容。用户选择颜色后,queryString被设置为选中的颜色,列表自然只剩这一项,不符合预期。Go按钮不可用且逻辑错误:
NavigationLink被放在NavigationView外部,脱离了SwiftUI的导航上下文,导致按钮无法正常响应导航逻辑。- 用
goToSecondView条件渲染目标视图,不符合NavigationLink的工作机制,同时没有任何逻辑控制按钮的启用状态。
修复后的代码
struct ContentView: View { let colors = ["Blue", "Cyan", "Teal", "Mint", "Green", "Yellow", "Orange", "Red", "Pink", "Purple", "Indigo"] var filteredColors: [String] { if queryString.isEmpty { return colors } else { return colors.filter { $0.localizedCaseInsensitiveContains(queryString) } } } @State private var queryString = "" @State private var selectedColor: String? // 单独存储选中的颜色 @State private var isNavigating = false var body: some View { NavigationView { List(filteredColors, id: \.self) { color in Text(color) .onTapGesture { selectedColor = color queryString = color // 可选:点击列表项时同步到搜索框 } } .navigationTitle("Colors") .searchable(text: $queryString, prompt: "Color Search", suggestions: { ForEach(colors.filter { $0.localizedCaseInsensitiveContains(queryString) }, id: \.self) { suggestion in Text(suggestion) .searchCompletion(suggestion) .onTapGesture { selectedColor = suggestion queryString = suggestion } } }) // 将Go按钮放入导航工具栏,纳入导航上下文 .toolbar { ToolbarItem(placement: .bottomBar) { NavigationLink(isActive: $isNavigating) { if let color = selectedColor { SecondView(querystring: color) } else { EmptyView() } } label: { Text("Go") } // 只有选中颜色后才启用按钮 .disabled(selectedColor == nil) } } .onSubmit(of: .search) { // 搜索提交时自动匹配并选中颜色,触发跳转 if let matchedColor = colors.first(where: { $0.localizedCaseInsensitiveContains(queryString) }) { selectedColor = matchedColor isNavigating = true } } } } } struct SecondView : View { var querystring : String var body : some View { Text("Selected Color: \(querystring)") .navigationTitle("Result") } }
修复说明
- 新增
selectedColor变量,专门存储用户选中的颜色,与搜索输入的queryString分离,保证列表过滤逻辑不受选中状态影响。 - 将
NavigationLink移至NavigationView的底部工具栏中,确保处于导航上下文内,同时通过disabled修饰符控制按钮可用性——只有选中颜色后按钮才会启用。 - 为列表项和搜索建议添加点击手势,点击时同步设置
selectedColor,确保选中操作能正确记录值。 - 优化搜索提交逻辑:用户提交搜索时,自动匹配并选中对应颜色,直接触发跳转,提升交互体验。
内容的提问来源于stack exchange,提问作者Philip
相关产品推荐
相关产品推荐

