如何使用UISearchBar实现文本与图片搜索?现有代码报错求助
解决图片数组与名称数组同步筛选的问题
首先得指出你当前代码里的核心错误:在筛选imageData的时候,你把UIImage类型的对象强行转成NSString——这完全行不通!UIImage是图片资源对象,根本不是字符串类型,这必然会导致编译错误或者运行时崩溃。
你的需求是根据名称筛选出对应的图片,而图片数组和名称数组是一一对应的,所以正确的思路是先对名称数组做筛选,再根据匹配的名称位置去取对应的图片。下面给你两种可行的解决方案:
方案一:基于现有数组结构快速修复
既然你已经有receivedData(名称数组)和imageData(图片数组)一一对应,我们可以先筛选出符合搜索条件的名称,再拿到它们在原数组中的索引,最后用索引提取对应的图片:
// SearchBar Text and Image filtering func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchBar.text?.isEmpty ?? true { isSearching = false view.endEditing(true) searchTableView.reloadData() } else { isSearching = true // 先筛选名称数组 filteredData = receivedData.filter { name in name.range(of: searchText, options: .caseInsensitive) != nil } // 获取匹配名称的索引,再提取对应图片 let matchingIndices = receivedData.indices.filter { index in receivedData[index].range(of: searchText, options: .caseInsensitive) != nil } filteredImage = matchingIndices.map { imageData[$0] } searchTableView.reloadData() } }
或者更高效的写法,一次遍历同时收集名称和图片,避免两次遍历数组:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchBar.text?.isEmpty ?? true { isSearching = false view.endEditing(true) searchTableView.reloadData() } else { isSearching = true var tempNames: [String] = [] var tempImages: [UIImage] = [] // 遍历名称数组,同时匹配并收集对应图片 for (index, name) in receivedData.enumerated() { if name.range(of: searchText, options: .caseInsensitive) != nil { tempNames.append(name) tempImages.append(imageData[index]) } } filteredData = tempNames filteredImage = tempImages searchTableView.reloadData() } }
方案二:创建模型类(更推荐,代码更健壮)
用两个平行数组来存名称和图片很容易出现顺序不一致的问题(比如后续修改数组时漏改其中一个),所以更专业的做法是创建一个模型类,把餐厅的名称和图片绑定在一起:
// 定义餐厅模型 struct Restaurant { let name: String let image: UIImage } // 初始化模型数组(替代原来的两个独立数组) let restaurants: [Restaurant] = [ Restaurant(name: "Burger Point", image: UIImage(named: "Burger Point")!), Restaurant(name: "Eating Point", image: UIImage(named: "Eating Point")!), Restaurant(name: "Food Garage", image: UIImage(named: "Food Garage")!), Restaurant(name: "Food Masters", image: UIImage(named: "Food Masters")!), Restaurant(name: "Food Plaza", image: UIImage(named: "Food Plaza")!), Restaurant(name: "Masala Junction 71", image: UIImage(named: "Masala Junction 71")!), Restaurant(name: "Samosa Express", image: UIImage(named: "Samosa Express")!), Restaurant(name: "Transform Diet", image: UIImage(named: "Transform Diet")!), Restaurant(name: "Urban Pind", image: UIImage(named: "Urban Pind")!) ] // 定义筛选后的模型数组 var filteredRestaurants: [Restaurant] = []
之后搜索逻辑就会变得非常简洁,直接筛选模型数组即可:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchBar.text?.isEmpty ?? true { isSearching = false view.endEditing(true) searchTableView.reloadData() } else { isSearching = true // 直接根据模型的name属性筛选 filteredRestaurants = restaurants.filter { restaurant in restaurant.name.range(of: searchText, options: .caseInsensitive) != nil } searchTableView.reloadData() } }
在UITableView的数据源方法里,你只需要根据isSearching状态来选择使用restaurants还是filteredRestaurants,直接获取模型的name和image即可,再也不用担心数组不匹配的问题。
内容的提问来源于stack exchange,提问作者Gurjit Singh
相关产品推荐
相关产品推荐

