UISearchController运动员名称筛选搜索及清空逻辑实现求助
Hey 我来帮你搞定这个搜索筛选的问题!你的核心需求应该是实现根据运动员名称片段过滤赛事列表,同时处理好搜索栏清空时恢复全部数据的逻辑对吧?先看看你现有代码里的几个小问题,再给你修正后的完整方案:
问题分析
你的当前代码存在几个潜在风险和逻辑漏洞:
- 强制解包
swimmers可选值:如果某个events对象的swimmers是nil,contains(where:)后面的!会直接导致崩溃 - 搜索文本没有预处理:没有去除空格或统一大小写,可能出现“张三”搜“张三 ”(带空格)找不到的情况
- 清空逻辑依赖
searchBarIsEmpty(),如果这个方法实现有问题,会导致清空时无法正确恢复原始数据
修正后的完整实现方案
1. 先确保searchBarIsEmpty()的正确实现
这个方法要准确判断搜索栏是否真的为空(包括只输入空格的情况):
func searchBarIsEmpty() -> Bool { // 去除首尾空格后判断是否为空字符串 return searchController.searchBar.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" == "" }
2. 改进filterContentForSearchText方法
这里重点处理可选值安全访问,同时优化搜索逻辑:
func filterContentForSearchText(_ searchText: String, scope: String = "All") { // 预处理搜索文本:转小写+去除首尾空格,确保不区分大小写且忽略空格干扰 let processedSearchText = searchText.lowercased().trimmingCharacters(in: .whitespacesAndNewlines) if searchBarIsEmpty() { // 搜索栏清空时,直接恢复原始数据数组 self.filarrayEV = self.arrayEV } else { // 过滤数组:只保留包含匹配运动员的赛事 self.filarrayEV = self.arrayEV.filter { event in // 安全处理swimmers可选值:如果赛事没有运动员数据,直接跳过 guard let swimmers = event.swimmers else { return false } // 检查当前赛事的运动员中,是否有名称包含搜索文本的 return swimmers.contains { swimmer in swimmer.swimmer.lowercased().contains(processedSearchText) } } } // 刷新表格数据 self.eventtable.reloadData() }
3. UISearchController的必要配置
为了让搜索逻辑流畅运行,还要确保你正确配置了搜索控制器的代理:
override func viewDidLoad() { super.viewDidLoad() // 初始化搜索控制器 let searchController = UISearchController(searchResultsController: nil) // 设置更新代理为当前控制器 searchController.searchResultsUpdater = self // 搜索时不模糊背景 searchController.obscuresBackgroundDuringPresentation = false // 设置搜索栏占位符 searchController.searchBar.placeholder = "搜索运动员名称" // 把搜索栏放到导航栏 navigationItem.searchController = searchController // 确保搜索栏在跳转时不会消失 definesPresentationContext = true } // 遵守UISearchResultsUpdating协议,实现搜索内容更新回调 extension YourViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { // 每次搜索栏内容变化时调用筛选方法 filterContentForSearchText(searchController.searchBar.text ?? "") } }
关键细节说明
- 安全处理可选值:用
guard let替代强制解包!,避免因为赛事没有运动员数据导致崩溃 - 搜索文本预处理:统一转小写并去除空格,保证搜索的容错性(比如用户输入大写或带空格都能匹配)
- 清空逻辑可靠性:直接把筛选数组赋值为原始数组,确保搜索栏清空时表格立刻恢复显示所有赛事
- 性能优化建议:如果你的赛事和运动员数据量很大,可以把过滤逻辑放到后台线程执行,避免主线程卡顿:
DispatchQueue.global().async { let filteredArray = self.arrayEV.filter { ... } DispatchQueue.main.async { self.filarrayEV = filteredArray self.eventtable.reloadData() } }
内容的提问来源于stack exchange,提问作者MW_DEVEL
相关产品推荐
相关产品推荐

