QQ10
QQ10

Reputation: 149

My searchBar filter is not function correctly

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()

}



}

My filter is not working correctly. Not sure where I did wrong. I think it might be something wrong with function searchBar function.

The filter is not working correct

The filter is not working correct2

Upvotes: 0

Views: 993

Answers (2)

Nirav D
Nirav D

Reputation: 72410

I have slightly changed your code, and with filter used contains and made some changes in delegate method of UISearchBar and used filteredStates with all the method of 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()
    }
}

Note: I haven't added code that you are using with TapGesture so don't forgot to add that.

Upvotes: 1

Tj3n
Tj3n

Reputation: 9923

Create another array to store the searched value

Implement filter logic on your searchBar: textDidChange method

Create a Bool (eg. isActive) to indicate if the search happened or cancelled on searchBarShouldBeginEditing and searchBarCancelButtonClicked

On your cellForRow, you can check for the Bool isActive to switch the let state = states[indexPath.row] to let state = filteredStates[indexPath.row]

Upvotes: 0

Related Questions