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

iOS中如何用单个UISearchBar同时实现名称与编号搜索

实现UISearchBar双条件(名称/编号)搜索的解决方案

我来帮你搞定这个双条件搜索的需求!首先得指出你现有代码的核心问题:你把名称和编号拆成了两个独立的数组,筛选时只处理了编号数组,没法关联对应的名称。所以第一步要做的是把每条数据的名称和编号绑定在一起,用一个模型类来管理,这样才能同时对两个字段进行筛选。

下面是具体的修改步骤:

1. 创建数据模型类

先定义两个结构体,对应你的JSON数据结构,这样能方便地解析和管理每条用户数据:

// 对应JSON里的顶层结构
struct UserResponse: Codable {
    let log: [UserData]
}

// 对应每条用户数据的结构
struct UserData: Codable {
    let Name: String?
    let clg_uniq: String?
}

2. 替换原有数据数组

把原来的clg_uniq和filteredData换成模型数组,明确数据类型:

let searchBar = UISearchBar()
var originalData: [UserData] = [] // 存储从服务器获取的所有原始数据
var filteredData: [UserData] = [] // 存储筛选后的数据
@IBOutlet weak var listTblView: UITableView!

3. 修改JSON解析逻辑

原来的解析只提取了编号,现在要把整个log数组解析成[UserData]:

// 假设你已经获取到了服务器返回的JSON Data对象
do {
    let decodedResult = try JSONDecoder().decode(UserResponse.self, from: jsonData)
    self.originalData = decodedResult.log
    self.filteredData = self.originalData // 初始化筛选数据为全部原始数据
    self.listTblView.reloadData()
} catch {
    print("JSON解析失败:\(error.localizedDescription)")
}

4. 更新UITableView数据源方法

现在filteredData是模型数组,需要从模型中取出名称和编号显示到cell上,同时处理nil的情况(避免label显示空白或nil):

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
    let currentData = filteredData[indexPath.row]
    
    // 处理名称为nil的情况,显示默认文本
    cell.userNameLbl.text = currentData.Name ?? "无名称"
    // 处理编号为nil的情况,显示默认文本
    cell.userClgLbl.text = currentData.clg_uniq ?? "无编号"
    
    return cell
}

5. 修改搜索逻辑,支持双条件筛选

更新searchBar(_:textDidChange:)方法,实现“名称包含搜索文本 或 编号包含搜索文本”的筛选逻辑,同时处理nil字段的情况:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    // 搜索文本为空时,显示全部数据
    guard !searchText.isEmpty else {
        filteredData = originalData
        DispatchQueue.main.async {
            self.listTblView.reloadData()
            searchBar.resignFirstResponder()
        }
        return
    }
    
    // 核心筛选逻辑:只要名称或编号匹配搜索文本,就保留这条数据
    filteredData = originalData.filter { userData in
        // 检查名称是否匹配(忽略大小写),如果名称为nil则不匹配
        let nameMatches = userData.Name?.range(of: searchText, options: .caseInsensitive) != nil
        // 检查编号是否匹配(忽略大小写),如果编号为nil则不匹配
        let idMatches = userData.clg_uniq?.range(of: searchText, options: .caseInsensitive) != nil
        
        // 两个条件满足其一即可
        return nameMatches || idMatches
    }
    
    DispatchQueue.main.async {
        self.listTblView.reloadData()
    }
}

这样修改后,你的搜索栏就能同时支持名称和编号的搜索了:用户输入名称时,会筛选出名称包含该文本的数据;输入编号时,会筛选出编号包含该文本的数据;甚至输入的文本同时出现在名称和编号里的条目也会被保留。

内容的提问来源于stack exchange,提问作者Naresh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:49:44