Search code examples
iosswiftuisearchcontroller

How do I display UISearchController results in a new view and not show the background of the tableView?


Quick question, I am using a UISearchController its working perfectly.

But I was wondering if it was possible to show a new view when I select the search bar?

Because when I am searching I do not want to see my tableView/background.


Solution

  • What you are referring to is the presentation context of the UISearchController.

    Here is a link to Apple's documentation on definesPresentationContext and the relevant piece of information we care about

    this property controls which existing view controller in your view controller hierarchy is actually covered by the new content

    If you are still working off this example UISearchController from before, you are already almost done and just need to look at the following line of code inside of viewDidLoad():

    self.definesPresentationContext = true
    

    The default value for this is false. Since it's set to true, we are telling the UITableViewController that it will be covered when the view controller or one of its descendants presents a view controller. In our case, we are covering the UITableViewController with the UISearchController.

    To address your question, hiding the tableView/background is as simple as clearing or switching the table's data source when the search bar is active. This is handled in the following bit of code.

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (self.userSearchController.active) {
            return self.searchUsers.count
        } else {
            // return normal data source count
        }
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell
        if (self.userSearchController.active && self.searchUsers.count > indexPath.row) {
            // bind data to the search data source
        } else {
            // bind data to the normal data source
        }
        return cell
    }
    

    When the search bar is dismissed, we want to reload the normal data source which is done with the following:

    func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    
        // Clear any search criteria
        searchBar.text = ""
    
        // Force reload of table data from normal data source
    }
    

    Here's a link to a great article on UISearchControllers and also gives a brief overview of their inner workings and view hierarchy.

    For future posts on SO, you should always try to include the relevant code samples so people are able to give the best feedback possible :)

    EDIT

    I think I misinterpreted your question a bit but the above is still relevant towards the answer. To display a special view when the search results are empty or nothing is typed in, do the following:

    1) Add a new UIView as a child of the TableView of your UITableViewController in the storyboard with the desired labels/images. This will be next to any prototype cells you may have.

    2) Create and wire up the outlets in your UITableViewController

    @IBOutlet var emptyView: UIView!
    @IBOutlet weak var emptyViewLabel: UILabel!
    

    3) Hide the view initially in viewDidLoad()

    self.emptyView?.hidden = true
    

    4) Create a helper function to update the view

    func updateEmptyView() {
        if (self.userSearchController.active) {
            self.emptyViewLabel.text = "Empty search data source text"
            self.emptyView?.hidden = (self.searchUsers.count > 0)
        } else {
            // Keep the emptyView hidden or update it to use along with the normal data source
            //self.emptyViewLabel.text = "Empty normal data source text"
            //self.emptyView?.hidden = (self.normalDataSource.count > 0)
        }
    }
    

    5) Call the updateEmptyView() after you've finished querying

    func loadSearchUsers(searchString: String) {
        var query = PFUser.query()
    
        // Filter by search string
        query.whereKey("username", containsString: searchString)
    
        self.searchActive = true
        query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
    
            if (error == nil) {
                self.searchUsers.removeAll(keepCapacity: false)
                self.searchUsers += objects as! [PFUser]
                self.tableView.reloadData()
                self.updateEmptyView()
            } else {
                // Log details of the failure
                println("search query error: \(error) \(error!.userInfo!)")
            }
            self.searchActive = false
        }
    }
    

    Hope that helps!