Bruno Bieri
Bruno Bieri

Reputation: 10236

How to replace the navigation bar with an UISearchBar?

I would like to replace the navigation bar with the search bar once shown and back.

OR

I would be fine if the navigation bar always laps over the content of my main view controller.


I set up the search controller like that:

_searchController = [[UISearchController alloc] initWithSearchResultsController:[[MySearchViewController alloc] init]];
_searchController.delegate = self;
_searchController.obscuresBackgroundDuringPresentation = TRUE;
_searchController.hidesNavigationBarDuringPresentation = TRUE;
_searchController.searchBar.placeholder = @"Search...";
_searchController.searchBar.delegate = self;

I show the search controller like that:

- (void)searchButtonTapped:(id)sender
{
  self.navigationItem.searchController = _searchController;
  [self.navigationController.view setNeedsLayout];
  [self.navigationController.view layoutIfNeeded];
  [self.navigationItem.searchController.searchBar becomeFirstResponder];
}

I hide the search controller like that:

- (void)willDismissSearchController:(UISearchController*)searchController
{
  self.navigationItem.searchController = nil;
  [self.navigationController.view setNeedsLayout];
}

I know there is the property searchController.hidesNavigationBarDuringPresentation which is close to what I want but exactly. Because the navigation bar only hides once I enter the search bar but I want it to hide already when I present the search bar.

As soon as I press the search icon button in the navigation bar it should be replaced with the search controller and only the search bar is being visible at the top. Does anyone know how to achieve this?


I already tried:

Upvotes: 0

Views: 382

Answers (1)

Bruno Bieri
Bruno Bieri

Reputation: 10236

I could make my first option to

I would like to replace the navigation bar with the search bar once shown and back.

work.

I used the approach to show and hide the left and right bat button items of the navigation item when the UISearchBar is being shown.

I would be interested if there is a simpler way to achieve the same?

@interface MyViewController() <UISearchControllerDelegate, SearchDelegate>
@end

@implementation MyViewController
{
  UIView*                    _navigationItemTitleView;
  NSArray<UIBarButtonItem*>* _leftBarButtonItems;
  NSArray<UIBarButtonItem*>* _rightBarButtonItems;
}

- (void)viewDidLoad
{
  _searchController        = [[UISearchController alloc] initWithSearchResultsController:[[MySearchViewController alloc] init]];
  // ....
  _navigationItemTitleView = self.navigationItem.titleView;
  _leftBarButtonItems      = self.navigationItem.leftBarButtonItems;
  _rightBarButtonItems     = self.navigationItem.rightBarButtonItems;
}

- (void)searchButtonTapped:(id)sender
{
  // show the search bar in the navigation item
  self.navigationItem.leftBarButtonItems  = nil;
  self.navigationItem.rightBarButtonItems = nil;
  self.navigationItem.titleView = _searchController.searchBar;
  _searchController.active = TRUE;
}

- (void)willDismissSearchController:(UISearchController*)searchController
{
  // hide the search bar and restore previous state of the navigation item
  self.navigationItem.leftBarButtonItems  = _leftBarButtonItems;
  self.navigationItem.rightBarButtonItems = _rightBarButtonItems;
  self.navigationItem.titleView           = _navigationItemTitleView;
}

Upvotes: 1

Related Questions