首页 > 解决方案 > 根据 UISearchBar 输入过滤 TableView (Swift)

问题描述

我想要做什么:我想根据 UISearchBar 中的用户输入来过滤上面有文本的 TableViewCells。

我的问题:我让它与简单的细胞一起工作。但是现在我使用了我用结构配置的自定义,现在我不知道如何过滤它们。

这是我的代码:

import UIKit
import Firebase

class searchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    
    @IBOutlet var searchy: UISearchBar!
    @IBOutlet var tabley: UITableView!
    
    var searchingNames = [String()]
    var searching = false
    var datas = [UserSearch]()

    override func viewDidLoad() {
        super.viewDidLoad()
        tabley.delegate = self
        tabley.dataSource = self
        searchy.delegate = self
        populateSearch()
        tabley.register(searchTableViewCell.nib(), forCellReuseIdentifier: searchTableViewCell.identifier)
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        if searching == true {
            return searchingNames.count
        } else{
            return datas.count
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if searching == true {
            let post = datas[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: searchTableViewCell.identifier, for: indexPath) as! searchTableViewCell
            cell.configure(with: post)
            return cell
        } else{
            let post = datas[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: searchTableViewCell.identifier, for: indexPath) as! searchTableViewCell
            cell.configure(with: post)
            return cell
        }
    }
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        
        searchingNames = datas.filter({$0.lowercased().prefix(searchText.count) == searchText.lowercased()}) // Cannot assign value of type '[UserSearch]' to type '[String]'
            // Value of type 'UserSearch' has no member 'lowercased'
        searching = true
        tabley.reloadData()
    }
}

struct UserSearch {
    var id: String
    var name: String
    var pfp: String
}

标签: swiftuitableviewstructfilteruisearchbar

解决方案


您必须过滤字符串属性UserSearch例如name.

而且您必须考虑用户清除搜索字段以重置searchingfalse

并且有一个更有效的 API 来检查子字符串


首先搜索结果的数组必须与数据源数组的类型相同

var searchingNames = [UserSearch]()

替换textDidChange

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    
   if searchText.isEmpty {
      searchingNames.removeAll()
      searching = false
   } else {
      searchingNames = datas.filter{ $0.name.range(of: searchText, options: [.anchored, .caseInsensitive]) != nil}
      searching = true
   }
   tabley.reloadData()
}
  • .anchored 从字符串的开头搜索
  • .caseInsensitive是不言自明的。

PS:输入cellForRow是错误的。在searching == true范围内替换

let post = datas[indexPath.row]

 let post = searchingNames[indexPath.row]

您甚至可以将代码简化为

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let post = searching ? searchingNames[indexPath.row] : datas[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: searchTableViewCell.identifier, for: indexPath) as! searchTableViewCell
    cell.configure(with: post)
    return cell
}

推荐阅读