如何在解析JSON数据的TableView中实现SearchBar搜索功能
解决方案
1. 修正数据类型
首先,filteredData的类型定义错误,你需要存储的是符合搜索条件的DetailSection模型对象,而非字符串,修改如下:
var filteredData = [DetailSection]() // 替换原来的 [String]
2. 填充???处的内容
???位置需要遍历你已经解析好的全量数据数组detailSection,这是所有模型对象的集合,我们要从中筛选符合搜索条件的项。
3. 重构搜索代理方法
原方法存在逻辑重复、判断错误的问题,以下是修正后的完整实现:
extension SearchViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { let trimmedText = searchText.trimmingCharacters(in: .whitespacesAndNewlines) if trimmedText.isEmpty { isSearching = false filteredData.removeAll() table.reloadData() return } isSearching = true // 遍历全量数据,筛选title或translation包含搜索文本的项 filteredData = detailSection.filter { section in let titleMatch = section.title.lowercased().contains(trimmedText.lowercased()) let translationMatch = section.translation.lowercased().contains(trimmedText.lowercased()) return titleMatch || translationMatch } table.reloadData() } }
4. 修正TableView数据源实现
原代码中numberOfRowsInSection每次调用decoder()会重复解析JSON,这是不合理的,应该在viewDidLoad中提前解析数据;同时cellForRowAt要区分搜索状态,使用对应的数据数组:
提前在viewDidLoad中完成数据解析:
class SearchViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() search.searchBar.delegate = self table.dataSource = self table.delegate = self view.addSubview(table) navigationItem.searchController = search // 提前解析数据,避免重复读取解析JSON文件 _ = decoder() } // ... 其他代码保持不变 }
修正TableView数据源方法:
extension SearchViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return isSearching ? filteredData.count : detailSection.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "DetailCell", for: indexPath) as! DetailCell let currentSection = isSearching ? filteredData[indexPath.row] : detailSection[indexPath.row] cell.title.text = currentSection.title cell.translation.text = currentSection.translation cell.transcription.text = currentSection.transcription cell.selectionStyle = .none return cell } }
关键说明
- 搜索时统一转为小写匹配,避免大小写敏感问题
- 提前解析JSON数据,避免TableView刷新时重复读取解析文件
- 严格区分搜索状态和正常状态,分别使用对应的数据数组填充单元格
内容的提问来源于stack exchange,提问作者user25462420
相关产品推荐
相关产品推荐

