json - 使用 UISearchBar 文本搜索 UITableView 单元格
问题描述
我想在UITableView
使用 UISearchBar 时显示过滤后的单元格,但它不起作用。我的搜索功能在我的代码的末尾。
import UIKit
struct User2: Codable {
let firstName: String
let lastName: String
let email: String
let userid: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case email = "email"
case userid = "user_id"
}
}
class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableview: UITableView!
@IBOutlet var searchBtn: UISearchBar!
private var dataSource = [User]() {
didSet {
self.tableview.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.tableview.register(UITableViewCell.self, forCellReuseIdentifier: "groupCell")
self.tableview.dataSource = self
self.tableview.delegate = self
let url = URL(string: "https://ex.com/ex.php")
URLSession.shared.dataTask(with: url!, completionHandler: { [weak self] (data, response, error) in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "An error occurred")
return
}
DispatchQueue.main.async {
self?.dataSource = try! JSONDecoder().decode([User].self, from: data)
}
}).resume()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableview.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "groupCell", for: indexPath)
let user = self.dataSource[indexPath.row]
cell.textLabel?.text = user.firstName + " " + user.lastName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user = self.dataSource[indexPath.row]
let userVC = DataViewController(user: user)
self.navigationController?.pushViewController(userVC, animated: true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
User2 = User2.filter({ (item) -> Bool in
let heading: NSString = ((item["firstName"]! as? String)! + (item["lastName"]! as! String)) as NSString
return (heading.range(of: searchText, options: NSString.CompareOptions.caseInsensitive).location) != NSNotFound
})
self.tableview.reloadData()
}
}
解决方案
更好的方法是拥有 2 个数据源,一个用于正常状态,另一个用于主动搜索,如下所示:
class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
private var dataSource = [User]() {
didSet {
self.tableview.reloadData()
}
}
private var searchDataSource: [User]? {
didSet {
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
...
self.searchBtn.delegate = self
}
// some changes to UITableView DataSource/Delegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.searchDataSource?.count ?? self.dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
let user = self.searchDataSource?[indexPath.row] ?? self.dataSource[indexPath.row]
...
}
}
最后使用以下扩展扩展UISearchBarDelegate
extension SearchViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
self.searchDataSource = nil
} else {
self.searchDataSource = self.dataSource.filter({
let fullName = $0.firstName + " " + $0.lastName
return fullName.range(of: searchText, options: [.anchored, .caseInsensitive]) != nil
})
}
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
if self.searchDataSource != nil && searchBar.text?.isEmpty ?? true {
self.searchDataSource = nil
}
}
}
产生
推荐阅读
- rdf - 指定属性数据类型——使用 SHACL、rdfs:range 还是自定义属性?
- python - 在 Python 中随机迭代(可能)巨大的位序列空间
- python - 是否可以在 Django 中的另一个模型中重用来自一个模型的注释?
- ruby-on-rails - 模型关联回调
- youtube - 了解 Youtube 数据 API 配额限制
- delphi - Delphi - 更改活动页面的选项卡颜色并在单击另一个选项卡后将其重置
- javascript - 有什么方法可以检查 Javascript 中的鼠标右键单击撤消事件?
- pytorch - 为什么 pow 在反向传递期间返回 nan?
- opencv - VideoCapture obj 未在 python 中读取(Ubuntu 20.04)
- javascript - 如何停止调整大小或锁定窗口大小或冻结 eel python 库中的窗口大小