3

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.

  • You want a special view displayed when the search bar is touched, but nothing is typed in it, correct? – Undo Dec 05 '15 at 22:17
  • 1
    yeh, nothing special just a plain view! –  Dec 05 '15 at 22:30
  • It sounds like you want something like https://github.com/nxtbgthng/UITableView-NXEmptyView - apply that to your search table view, and you should be good to go. Let me know if that's the solution, I can post it as an answer. – Undo Dec 05 '15 at 23:40
  • 1
    Isn't there a more of a normal when of doing it without installing that? –  Dec 05 '15 at 23:42
  • If you want to go the vanilla route, see http://stackoverflow.com/a/17436782/1849664. I generally go with the NXEmptyView option simply because it's cleaner. – Undo Dec 05 '15 at 23:43

1 Answers1

2

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!

Russell
  • 3,099
  • 2
  • 14
  • 18
  • 1
    Thanks for the answer! I have added my code above, and I think I have done everything you said, it's what I already had. But still for example, I add a background to my table view(or if I have several images), it also shows it while I'm searching. I was just looking at this post http://stackoverflow.com/questions/31776376/instagram-explorer-searchbar-and-tableview/32989085#32989085 and they're he connects the results to a new view in storyboard. I did so, and a new view appeared but I'm just trying to figure out how to show the results in the new view and not the old one! –  Dec 06 '15 at 01:23
  • 1
    Just added a *massive* edit that I think answers your real question haha. Take a look and let me know if it helps :) – Russell Dec 06 '15 at 01:25
  • 1
    I shall have fun with that :) when you say create a helper, do you mean a swift file? –  Dec 06 '15 at 01:41
  • 1
    Nope, it's just another function in your UITableViewController class – Russell Dec 06 '15 at 02:33
  • 1
    It's a separate function. `listingSearchController` was just a typo, should have been `userSearchController` – Russell Dec 06 '15 at 03:03
  • 1
    Think, I have it working. How should I set the else up, not too sure what to replace normalDataSource with.. –  Dec 06 '15 at 03:17
  • 1
    Good to hear! What do you populate the table with normally? That's what you should put in the else statement and is what `(self.normalDataSource.count > 0)` was referring to. That way the emptyView is hidden when there is data being displayed in the table – Russell Dec 06 '15 at 03:28
  • 1
    Yeh i'm trying to figure that out! :S heres a screenshot of what it looks like at the moment, http://i.stack.imgur.com/1vAHp.png , let me know if anythings wrong there –  Dec 06 '15 at 03:34
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97098/discussion-between-russell-and-theo-sidebotham). – Russell Dec 06 '15 at 03:35
  • 1
    Just a quick question if thats ok ;) I know you know alot about parse! I was just wondering as I'm trying to have resizable images on my feed and not 1 single size, if the best way is to get the image size from Parse in the background to be able to resize the cell's correctly before displaying them to the user(using UITableViewAutomaticDimension)? I have tried 1 way (not getting the image size beforehand from Parse) and basically when I launch my app the image appears empty and the cell size is 0 untill I scroll or update the page. –  Jan 15 '16 at 18:39
  • 1
    I have posted a previous question, and a user helped me but the code he gave me updates the cell's automatically when the view is loaded. But with that it jumps while is resizing and looks very "rubishy"! If you think the getting the image size in the background from Parse could work, is there any documentations on it?! –  Jan 15 '16 at 18:39