Swift UITableView搭配UISearchController搜索时仅展示技能vName实现问题
问题根因
你的代码存在4个核心问题导致搜索功能不生效:
- 搜索状态下分区数量逻辑错误:无论是否触发搜索,分区数始终返回原分类的总数量,导致搜索时每个分区都会重复展示所有匹配结果
- API请求成功后未刷新列表:接口拿到数据后仅打印了结果,没有触发列表刷新,界面一直使用初始本地旧数据
- 搜索状态下分区头部未适配:搜索场景下仍展示原分类的头部标题,不符合搜索交互逻辑
- 过滤逻辑存在崩溃风险:对可选类型vName直接强制解包,若vName为空会直接触发闪退
修复代码
1. 修改分区数量逻辑
override func numberOfSections(in tableView: UITableView) -> Int { if isSearching && !searchController.searchBar.text!.isEmpty { return 1 } return viewModel.categorySkills.count }
2. 修改分区头部标题逻辑
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { if isSearching && !searchController.searchBar.text!.isEmpty { return "搜索结果" } return viewModel.categorySkills[section].vName }
3. 接口请求成功后刷新列表
func callAPI(){ UserApi().getTradieSkills().subscribe(onNext: { [weak self] (result: Result<TradeSelectionViewModel>) in guard let self = self else { return } switch result { case .success(model: _): self.tableView.reloadData() case .error(error: _): print("error") } }).disposed(by: bag) }
4. 优化过滤逻辑避免强制解包崩溃
func updateSearchResults(for searchController: UISearchController) { guard let searchString = searchController.searchBar.text else { return } if searchString.isEmpty { filteredObjects.removeAll() }else{ filteredObjects = viewModel.categorySkills .flatMap({ $0.skill }) .filter({ guard let skillName = $0.vName?.lowercased() else { return false } return skillName.contains(searchString.lowercased()) }) } isSearching = searchController.isActive tableView.reloadData() }
补充说明
如果你需要搜索结果也按原分类分组展示,只需把filteredObjects改为分组结构[[SkillDTO]],过滤时保留有匹配skill的分类,每个分类下仅保留匹配的skill即可,对应适配列表的数据源方法就行。
内容的提问来源于stack exchange,提问作者Pinal
相关产品推荐
相关产品推荐

