How to Use Uisearchcontroller in iOS 8 Where the Uisearchbar Is in My Navigation Bar and Has Scope Buttons

How do I use UISearchController in iOS 8 where the UISearchBar is in my navigation bar and has scope buttons?

You're bumping into a "design issue" where the scopeBar is expected to be hidden when the searchController is not active.

The scope bar buttons appear behind (underneath) the search bar since that's their location when the search bar becomes active and animates itself up into the navigation bar.

When the search is not active, a visible scope bar would take up space on the screen, distract from the content, and confuse the user (since the scope buttons have no results to filter).

Since your searchBar is already located in the titleView, the (navigation and search) bar animation that reveals the scope bar doesn't occur.

  • The easiest option is to locate the search bar below the
    navigation bar, and let the searchBar animate up into the title
    area when activated. The navigation bar will animate its height,
    making room to include the scope bar that was hidden. This will all
    be handled by the search controller.
  • The second option, almost as easy, is to use a Search bar button
    icon, which will animate the searchBar and scopeBar down into
    view over the navigation bar.

    - (IBAction)searchButtonClicked:(UIBarButtonItem *)__unused sender {
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.hidesNavigationBarDuringPresentation = NO;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.definesPresentationContext = YES;
    self.searchController.searchBar.scopeButtonTitles = @[@"Posts", @"Users", @"Subreddits"];
    [self presentViewController:self.searchController animated:YES completion:nil];
    }
  • If you want the searchBar to remain in the titleView, an animation
    to do what you want is not built in. You'll have to roll your own
    code to handle the navigationBar height change and display your own
    scope bar (or hook into the internals, and animate the built-in
    scopeBar down and into view).

    If you're fortunate, someone else has written willPresentSearchController: code to handle the transition you want.

  • If you want to always see a searchBar and scopeBar, you'll probably have to ditch using the built-in scopeBar, and replace it with a UISegmentedControl which the user will always see, even when the search controller is not active.

Update:

This answer suggested subclassing UISearchController to change its searchBar's height.

How do I set the UISearchController's searchBar to a view that isn't the tableHeaderView or navigationItem.titleview?

If you have a blank UIView that is placed above the tableview.

let's assume you have an outlet to that blank UIView called searchContainer.
Then you can add the search bar of the UISearchController to that view by adding the following line

searchContainer.addSubview(searchController.searchBar)

Unable to add UISearchController's search bar into navigationbar and delegate methods not getting called

Just define UISearchController as property then everything working fine.

I have tested below in the sample project.

  class ViewControllerName: UIViewController{
let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
super.viewDidLoad()
let search = UISearchController(searchResultsController: nil)
self.navigationItem.searchController = search
self.navigationItem.searchController!.searchBar.delegate = self
self.navigationItem.searchController!.searchResultsUpdater = self
self.navigationItem.searchController?.searchBar.showsCancelButton = true
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
print("Called")
}

func updateSearchResults(for searchController: UISearchController) {
print("Called")
}
}

Hope it will work for you.

How is UISearchController meant to be used without UINavigationController?

You may be over-thinking this. You could perfectly well use a UISearchController without a navigation controller or a table view. The only reason people use a table view is that it's nice to have some way of displaying the search results. But UISearchController is a perfectly ordinary view controller and just does its job regardless. It really is the simplest thing in the world — that's the beauty of it. It's so simple, it can do anything with regard to search.

Here's the tiniest example I could think of. This is basically the entire code of the app:

class ViewController: UIViewController {
var sc : UISearchController?
override var prefersStatusBarHidden: Bool { true }
override func viewDidLoad() {
super.viewDidLoad()
let vc2 = ViewController2()
let sc = UISearchController(searchResultsController: vc2)
self.sc = sc
sc.searchResultsUpdater = vc2
let sb = sc.searchBar
self.view.addSubview(sb)
}
}
class ViewController2: UIViewController, UISearchResultsUpdating {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .green
}
func updateSearchResults(for searchController: UISearchController) {
guard searchController.isActive else {return}
if let t = searchController.searchBar.text, !t.isEmpty {
print("You are searching for", t)
}
}
}

That illustrates perfectly what UISearchController does, namely almost nothing. It just responds to the user tapping in the search bar by putting up a secondary view controller and signaling when the user types in the search bar. Everything else is up to you.



Related Topics



Leave a reply



Submit