使用 UISearchBar 文本搜索 UITableView 单元格
Posted
技术标签:
【中文标题】使用 UISearchBar 文本搜索 UITableView 单元格【英文标题】:Search UITableView cells using UISearchBar text 【发布时间】:2019-04-12 07:27:03 【问题描述】:我想使用 UISearchBar 在UITableView
中显示过滤后的单元格,但它不起作用。我的搜索功能在我的代码末尾。
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()
【问题讨论】:
你的NSString
- String
舞蹈太可怕了。您需要第二个数组用于搜索结果以保留整个原始数组。而且你不能过滤类型。
【参考方案1】:
更好的方法是拥有 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
产生
【讨论】:
将此代码粘贴到我的应用程序@AamirR 时出现很多错误【参考方案2】:我认为应该在dataSource
上应用过滤器,其中dataSource
类似于[User2]
:
let filteredArr: [User] = dataSource.filter( $0.firstName.lowercased().contains(searchText.lowercased()) || $0.lastName.lowercased().contains(searchText.lowercased()) )
【讨论】:
【参考方案3】:您可以尝试在dataSource
中应用过滤,例如:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
let filteredArray = dataSource.filter( user in
let username = "\(user.firstName) \(user.lastName)"
return username.range(of: searchText, options: .caseInsensitive) != nil
)
self.tableview.reloadData()
【讨论】:
以上是关于使用 UISearchBar 文本搜索 UITableView 单元格的主要内容,如果未能解决你的问题,请参考以下文章
Swift iOS 8+ UISearchBar图标,占位符和文本居中