SwiftUI中无需NavigationView实现带自动补全的搜索栏及列表搜索
完全可以实现,核心思路是通过状态变量管理搜索文本、建议列表和过滤结果,配合自定义搜索栏、自动建议弹窗以及过滤后的列表完成,无需依赖NavigationView。以下是完整实现方案:
核心逻辑拆解
- 用
@State变量维护搜索输入、建议面板显示状态、原始数据集合和过滤后的数据 - 自定义搜索栏(包含输入框、清除按钮),监听输入变化实时过滤建议和列表数据
- 自动建议面板通过条件渲染显示,点击建议项自动填充搜索文本并收起面板
- 列表直接绑定过滤后的数据集合,实现搜索结果实时更新
完整代码示例
import SwiftUI struct ContentView: View { // 模拟原始业务数据(可替换为你的表单数据源) private let originalItems = ["Apple", "Banana", "Blueberry", "Cherry", "Grape", "Green Apple", "Lemon", "Mango", "Orange", "Peach"] // 搜索相关状态管理 @State private var searchText = "" @State private var showSuggestions = false // 计算属性:过滤后的自动建议列表(不区分大小写匹配) private var filteredSuggestions: [String] { guard !searchText.isEmpty else { return [] } return originalItems.filter { $0.localizedCaseInsensitiveContains(searchText) } } // 计算属性:最终显示的列表数据 private var filteredItems: [String] { guard !searchText.isEmpty else { return originalItems } return originalItems.filter { $0.localizedCaseInsensitiveContains(searchText) } } var body: some View { VStack(spacing: 0) { // 自定义搜索栏 HStack(spacing: 8) { Image(systemName: "magnifyingglass") .foregroundColor(.gray) TextField("搜索...", text: $searchText, onEditingChanged: { isEditing in showSuggestions = isEditing && !searchText.isEmpty }) .foregroundColor(.primary) // 清除输入按钮 if !searchText.isEmpty { Button(action: { searchText = "" showSuggestions = false }) { Image(systemName: "xmark.circle.fill") .foregroundColor(.gray) } } } .padding(.horizontal, 16) .padding(.vertical, 12) .background(Color(.systemGray6)) .cornerRadius(8) .padding(.horizontal, 16) .padding(.top, 16) // 自动建议面板 if showSuggestions && !filteredSuggestions.isEmpty { List(filteredSuggestions, id: \.self) { suggestion in Button(action: { searchText = suggestion showSuggestions = false // 点击建议后收起键盘 UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) }) { Text(suggestion) } } .listStyle(.plain) .frame(height: CGFloat(filteredSuggestions.count * 44)) .padding(.horizontal, 16) .cornerRadius(8) .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2) } // 你的表单列表(替换为已有表单内容即可) List(filteredItems, id: \.self) { item in Text(item) .padding(.vertical, 8) } .listStyle(.plain) .padding(.top, 8) Spacer() } // 点击空白区域收起键盘和建议面板 .onTapGesture { showSuggestions = false UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
关键细节说明
- 自定义搜索栏:完全脱离NavigationView,用HStack手动实现搜索框样式,支持清除输入和编辑状态监听
- 匹配规则自定义:示例用
localizedCaseInsensitiveContains实现包含匹配,可根据需求改为前缀匹配(hasPrefix)或其他规则 - 交互优化:通过点击空白区域、建议项或清除按钮,统一管理键盘和建议面板的显示/隐藏
- 表单适配:将示例中的
List(filteredItems)替换为你已有的表单内容,只需把表单数据源绑定到filteredItems即可实现搜索过滤
内容的提问来源于stack exchange,提问作者EN_Tech
相关产品推荐
相关产品推荐

