Swift 4中如何通过搜索栏过滤PostDataModel数组的标题?
针对PostDataModel数组的标题搜索过滤方案
嘿,作为Swift新手你已经找对方向啦!其实你当前的代码思路没问题,只是有几个细节可以优化,让搜索更灵活准确,下面我来帮你调整一下:
核心逻辑梳理
要过滤PostDataModel数组,本质就是用Swift数组的filter方法遍历每个模型对象,判断它的postTitle是否符合搜索条件——这和过滤字符串数组的逻辑类似,只是要访问模型的对应属性而已。
优化搜索代理方法
你现有的代码里有两个可以改进的地方:一是searchBarSearchButtonClicked里用了完全匹配(==),用户必须输入和标题完全一样的文本才能搜到,体验不好;二是textDidChange里的可选值处理和闭包可以更简洁。
下面是优化后的完整代码:
// 先确保你在ViewController里定义了这些变量 var postsArray: [PostDataModel] = [] var filteredTableData: [PostDataModel] = [] var shouldShowSearchResults = false //MARK: - Search bar methods extension ViewController: UISearchBarDelegate { func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { // 收起键盘 searchBar.resignFirstResponder() guard let searchText = searchBar.text?.lowercased(), !searchText.isEmpty else { shouldShowSearchResults = false tablePosts.reloadData() return } // 和实时搜索保持一致的匹配逻辑,不用严格相等 filteredTableData = postsArray.filter { $0.postTitle.lowercased().contains(searchText) } shouldShowSearchResults = true tablePosts.reloadData() } func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { let trimmedText = searchText.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() if trimmedText.isEmpty { shouldShowSearchResults = false // 清空过滤数组,避免残留数据 filteredTableData.removeAll() tablePosts.reloadData() } else { shouldShowSearchResults = true // 简化闭包写法,直接访问模型的postTitle属性 filteredTableData = postsArray.filter { $0.postTitle.lowercased().contains(trimmedText) } tablePosts.reloadData() } } // 补充取消按钮的处理,体验更完整 func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { searchBar.text = "" shouldShowSearchResults = false filteredTableData.removeAll() searchBar.resignFirstResponder() tablePosts.reloadData() } }
额外优化:忽略大小写和特殊字符
如果想让搜索更智能(比如忽略大小写、忽略重音符号如é/è),可以用range(of:options:)来实现:
filteredTableData = postsArray.filter { $0.postTitle.range(of: trimmedText, options: [.caseInsensitive, .diacriticInsensitive]) != nil }
表格数据源的配合
别忘了在tableView的数据源方法里,根据shouldShowSearchResults返回对应的数据:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return shouldShowSearchResults ? filteredTableData.count : postsArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath) let post = shouldShowSearchResults ? filteredTableData[indexPath.row] : postsArray[indexPath.row] // 给cell设置post的数据,比如cell.titleLabel.text = post.postTitle return cell }
这样调整后,你的搜索功能就能流畅地根据标题过滤PostDataModel数组啦~
内容的提问来源于stack exchange,提问作者papesky
相关产品推荐
相关产品推荐

