You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:54:28