import UIKit
class ViewController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
var filteredStates = [State]()
var states = [
State(stateName: "Alabama", abbreviation: "AL" ),
State(stateName: "Alaska", abbreviation: "AK" ),
State(stateName: "Arizona", abbreviation: "AZ"),
State(stateName: "Arkansas", abbreviation: "AR"),
State(stateName: "California", abbreviation: "CA"),
State(stateName: "Colorado", abbreviation: "CO"),
State(stateName: "Connecticut", abbreviation: "CT"),
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
searchBar.delegate = self
filteredStates = states
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tableView.addGestureRecognizer(tap)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as UITableViewCell
let state = states[indexPath.row]
cell.textLabel?.text = state.stateName
cell.detailTextLabel?.text = state.abbreviation
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredStates.count
}
// This method updates filteredData based on the text in the Search Box
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredStates = searchText.isEmpty ? states : states.filter { (item: State) -> Bool in
return item.stateName.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
print(filteredStates)
tableView.reloadData()
}
// Wehn search bar being editing, cancel button pops up
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
}
// When search bar cancel button clicked
// Cancel button dismiss, search text is empty, keyboard dismiss
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
// when click outside of keyboard
// Keyboard dismiss
func handleTap() {
self.view.endEditing(true)
}
// When clicked search button
// keyboard dismiss
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
}
我的过滤器无法正常工作。不知道我错在哪里。我认为函数searchBar函数可能有问题。
答案 0 :(得分:1)
我稍微更改了您的代码,并使用filter
包含并对UISearchBar的委托方法进行了一些更改,并将filteredStates
与UITableViewDataSource
的所有方法一起使用。
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
var filteredStates = [State]()
var states = [
State(stateName: "Alabama", abbreviation: "AL" ),
State(stateName: "Alaska", abbreviation: "AK" ),
State(stateName: "Arizona", abbreviation: "AZ"),
State(stateName: "Arkansas", abbreviation: "AR"),
State(stateName: "California", abbreviation: "CA"),
State(stateName: "Colorado", abbreviation: "CO"),
State(stateName: "Connecticut", abbreviation: "CT"),
]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
filteredStates = states
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredStates.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell")!
//Access data from filteredStates array not from states array
cell.textLabel?.text = self.filteredStates[indexPath.row].stateName
cell.detailTextLabel?.text = self.filteredStates[indexPath.row].abbreviation
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(self.filteredStates[indexPath.row].stateName)
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = true
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.filteredStates = searchText.isEmpty ? states : states.filter( { $0.stateName.localizedCaseInsensitiveContains(searchText) })
self.tableView.reloadData()
}
func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
searchBar.showsCancelButton = false
searchBar.text = ""
self.filteredStates = states
self.tableView.reloadData()
}
}
注意:我没有添加您使用TapGesture
的代码,所以不要忘记添加。
答案 1 :(得分:0)
创建另一个数组来存储搜索值
在searchBar: textDidChange
方法
创建一个Bool(例如。isActive
),以指示在searchBarShouldBeginEditing
和searchBarCancelButtonClicked
上发现或取消了搜索
在cellForRow
上,您可以查看Bool isActive
以将let state = states[indexPath.row]
切换为let state = filteredStates[indexPath.row]