You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中无需NavigationView实现带自动补全的搜索栏及列表搜索

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:31:04