0x0
0x0

Reputation: 373

Why does my SearchController only match the first character?

I have Data in Dictionary format like this:

var data: [[String:AnyObject]] =

[
  [
    "id": "1",
    "title": "A Title",
    "Detail": "This is a String"
  ],      
  [
    "id": "2",
    "title": "A Title Again",
    "Detail": "This is a String"
  ]
]

and my TableViewController lists all "title" data.

I am implementing a SearchController for user to search for a specific data from the "title" only.

My code seems to display results matching just the first character from the search query.

For example: if user inputs "A", all the title results with "A" are displayed but if user goes ahead with "A " (with a space), everything in the searchResult disappears.

Here's my attempt:

class TVC: UITableViewController, UISearchResultsUpdating {

let Search = data
var filteredSearch = [[String:AnyObject]]()
var resultSearchController = UISearchController()

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if (self.resultSearchController.active)
    {
        return self.filteredSearch.count
    }
    else
    {
        return self.Search.count
    }

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell?

    if (self.resultSearchController.active)
    {

        cell!.textLabel?.text = (filteredSearch[indexPath.row]["title"] as! String)
        return cell!
    }
    else
    {
        cell!.textLabel?.text = (Search[indexPath.row]["title"] as! String)
        return cell!
    }


}



func updateSearchResultsForSearchController(searchController: UISearchController)
{
    self.filteredSearch.removeAll(keepCapacity: false)

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
    let array = (self.Search as NSArray).filteredArrayUsingPredicate(searchPredicate)
    self.filteredSearch = array as! [[String:AnyObject]]

    self.tableView.reloadData()


}

Upvotes: 1

Views: 647

Answers (1)

Losiowaty
Losiowaty

Reputation: 8006

You got your predicate wrong. The way it is setup now, self in predicate refers to the objects in an array which are dictionaries, and dictionaries don't have substrings :) In order to make it work, we have to tell the predicate to check value under specific key. This can be done in two ways :

let searchPredicate = NSPredicate(format: "title CONTAINS[c] %@", searchController.searchBar.text!)
// OR
let searchPredicate = NSPredicate(format: "SELF[\"title\"] CONTAINS[c] %@", searchController.searchBar.text!)

This way, the predicate will check the value under title key if it contains the text from the search bar.

I do not know why it worked with single letter though.

Upvotes: 2

Related Questions