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

如何实现点击键盘搜索按钮后再执行列表过滤?

解决实时搜索卡顿:改为点击搜索按钮再执行搜索

你的问题核心在于当前每输入一个字符就会触发searchTerm更新,进而导致List实时执行全量过滤——如果数据集较大,这种频繁计算必然会引发卡顿。我们可以通过分离输入文本和过滤触发时机来彻底解决这个问题,具体实现步骤如下:

1. 修改SearchBar组件,添加搜索按钮回调

先给自定义的SearchBar新增一个闭包参数,用来在用户点击搜索按钮时通知父视图执行搜索。同时我们可以添加取消按钮的处理,进一步提升用户体验:

import Foundation
import SwiftUI

struct SearchBar: UIViewRepresentable {
    @Binding var text: String
    var placeholder: String
    // 新增:搜索按钮点击的回调闭包,用于通知父视图执行搜索
    var onSearchTriggered: (String) -> Void

    class Coordinator: NSObject, UISearchBarDelegate {
        @Binding var text: String
        let onSearchTriggered: (String) -> Void

        init(text: Binding<String>, onSearchTriggered: @escaping (String) -> Void) {
            _text = text
            self.onSearchTriggered = onSearchTriggered
        }

        // 保持实时同步搜索栏输入文本,但不触发过滤逻辑
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            text = searchText
        }

        // 点击搜索按钮时,触发父视图的搜索逻辑并收起键盘
        func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
            onSearchTriggered(text)
            searchBar.resignFirstResponder()
        }

        // 点击取消按钮时,清空输入内容和过滤条件
        func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
            text = ""
            onSearchTriggered("")
            searchBar.resignFirstResponder()
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text, onSearchTriggered: onSearchTriggered)
    }

    func makeUIView(context: Context) -> UISearchBar {
        let searchBar = UISearchBar(frame: .zero)
        searchBar.delegate = context.coordinator
        searchBar.placeholder = placeholder
        searchBar.searchBarStyle = .minimal
        searchBar.autocapitalizationType = .none
        searchBar.showsCancelButton = true // 显示取消按钮,优化操作体验
        return searchBar
    }

    func updateUIView(_ uiView: UISearchBar, context: Context) {
        uiView.text = text
    }
}

2. 调整ContentView,分离输入与过滤逻辑

在ContentView中新增一个专门用于过滤的变量,只有在用户点击搜索按钮时才更新它,这样List的过滤操作只会在需要的时候执行:

struct ContentView: View {
    @State private var searchInput = "" // 实时同步搜索栏输入的文本
    @State private var activeSearchTerm = "" // 实际用于过滤的文本,仅在点击搜索时更新

    // 替换成你的实际数据模型类型
    let gesetzestextTEMPO: [YourDataModel] = []

    // 提取过滤逻辑为计算属性,让代码更整洁易维护
    private var filteredItems: [YourDataModel] {
        gesetzestextTEMPO.filter { item in
            guard !activeSearchTerm.isEmpty else { return true }
            let lowercasedSearch = activeSearchTerm.localizedLowercase
            return item.titel1.localizedLowercase.contains(lowercasedSearch) ||
                   item.artikel.localizedLowercase.contains(lowercasedSearch) ||
                   item.marginale.localizedLowercase.contains(lowercasedSearch) ||
                   item.absatz0.localizedLowercase.contains(lowercasedSearch) ||
                   item.absatz0litaz.localizedLowercase.contains(lowercasedSearch)
        }
    }

    var body: some View {
        VStack {
            SearchBar(text: $searchInput, placeholder: "Suche") { searchText in
                // 点击搜索按钮时,更新过滤用的文本
                activeSearchTerm = searchText
            }
        }
        List {
            ForEach(filteredItems) { item in
                Part13(gesetzestextTEMPO: item, searchTerm: $activeSearchTerm)
            }
        }
    }
}

核心原理说明

  • 输入与过滤解耦:searchInput仅负责同步用户在搜索栏的输入,不会触发List的过滤;activeSearchTerm才是驱动List过滤的变量,只有点击搜索按钮时才会更新。
  • 减少不必要计算:原来每次输入字符都会执行一次全量过滤,现在只有在用户明确点击搜索时才执行一次,大幅减少了性能消耗。
  • 用户体验优化:添加取消按钮,让用户可以快速清空搜索状态,操作更流畅。

内容的提问来源于stack exchange,提问作者iSoldier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:37:41