0
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 函数可能有问题。

过滤器工作不正常

过滤器工作不正常2

4

2 回答 2

1

我稍微更改了您的代码,并filter使用了 contains 并对 UISearchBar 的委托方法进行了一些更改,并filteredStatesUITableViewDataSource.

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所以不要忘记添加它。

于 2017-02-23T06:33:57.533 回答
0

创建另一个数组来存储搜索到的值

searchBar: textDidChange在您的方法上实现过滤器逻辑

创建一个 Bool(例如isActive)来指示搜索是否发生或searchBarShouldBeginEditing取消searchBarCancelButtonClicked

在您的 上cellForRow,您可以检查 BoolisActive以切换let state = states[indexPath.row]let state = filteredStates[indexPath.row]

于 2017-02-23T03:03:29.817 回答