13

I have a UITableViewController T that contains a UISearchDisplayController and UISearchBar in the standard way (everything defined in a nib). T is then contained as a child view controller in the standard way by some other view controller.

The search bar displays correctly:

normal search bar

But when I tap into the search bar do actually search, the search bar gets taller, and the content inside the search bar drops down by what looks like about 20 pixels (er, the height of the status bar? coincidence?) Like so:

weird search bar is too tall

What's up with that? It's too tall. Also, the animation that makes it look like that is ungainly. Any way to prevent that unsightly growth?

Jakub
  • 13,712
  • 17
  • 82
  • 139
Colin
  • 3,670
  • 1
  • 25
  • 36

6 Answers6

8

I managed to solve a very similar problem to the one you're experiencing by programmatically setting the UISearchController up like so:

Note ~ The error persists if hidesNavigationBarDuringPresentation is not set to NO.

#pragma mark - View Life Cycle

- (void)viewDidLoad {
    [super viewDidLoad];

    self.results = [[NSArray alloc] init];

//  1  \\ Results Table View
    UITableView *searchResultsTableView = [[UITableView alloc] initWithFrame:self.tableView.frame];
    [searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:Identifier];
    searchResultsTableView.delegate = self;
    searchResultsTableView.dataSource = self;

//  2  \\ init search results table view & setting its table view
    self.searchResultsTableViewController = [[UITableViewController alloc] init];
    self.searchResultsTableViewController.tableView = searchResultsTableView;
    self.searchResultsTableViewController.view.backgroundColor = [UIColor blackColor];

//  3  \\ init a search controller with it's tableview controller for results
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.searchResultsTableViewController];
    self.searchController.hidesNavigationBarDuringPresentation = NO;    //  √
    self.searchController.searchResultsUpdater = self;
    self.searchController.delegate = self;
    self.searchController.searchBar.barTintColor = [UIColor blackColor];

//  4  \\ Make an appropriate search bar (size, color, attributes) and add it as the header
    [self.searchController.searchBar sizeToFit];
    self.tableView.tableHeaderView = self.searchController.searchBar;
    self.tableView.tableHeaderView.backgroundColor = [UIColor blackColor];

//  5  \\ Enable presentation context
    self.definesPresentationContext = YES;
    self.tableView.backgroundColor = [UIColor clearColor];
    self.currentUser = [PFUser currentUser];
}

Added Further Details:

  1. Interface Builder: UIViewController (not UITableViewController)
  2. Add a UITableView with Constraints:

    a. enter image description here

    b. *My Nav Bar is custom height - your "Top Space to: Top Layout Guide" may be changed

  3. Add the Delegate & Data Source outlets from the added Table View to the UIViewController

    a. Don't forget to do so programmatically:

    @interface AddUsersViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
    
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    
  4. In your Interface Extension:

    a. Set your UISearchConroller's Delegate and Data Source:

    #import "AddUsersViewController.h"
    
    #define ResultsTableView self.searchResultsTableViewController.tableView
    #define Identifier @"Cell"
    
    @interface AddUsersViewController () <UISearchControllerDelegate, UISearchResultsUpdating>
    
    @property (nonatomic) UISearchController *searchController;
    @property (nonatomic) UITableViewController *searchResultsTableViewController;
    @property (nonatomic, weak) UIBarButtonItem *leftBarButton;
    @property (nonatomic) NSArray *results;
    
    @end
    

Although this worked for me, I have discovered that there are other possible scenarios that could be causing this. My "issue" wasn't that the search bar moved down 20px (or so) but that it moved up. I attributed this to a customized UINavigationBar header that included an image title and custom NavBarButtons. With that in mind, here are two more possible solutions:

.

Original Scenarios:

  1. Your Container View's extendedLayoutIncludesOpaqueBars Property

    a. Storyboard: Check √ "Under Opaque Bars" for the table views in storyboard.

    b. Programmatically: yourTableView(s).extendedLayoutIncludesOpaqueBars = YES;

.

  1. Set scopeButtonTitles to an empty array. (below)

    self.searchController = UISearchController(searchResultsController: nil);
    self.searchController.searchResultsUpdater = self;
    self.searchController.searchBar.scopeButtonTitles = [];
    self.tableView.tableHeaderView = self.searchController.searchBar;
    

The later two answers come from THIS question and may prove to be beneficial in checking out too.

Thanks to BananaNeil's research and testing, he discovered that if you follow the my recommendations and set your searchController.searchBar.y = 0 your search bar should be exactly where you were hoping it would be. √

Community
  • 1
  • 1
ChrisHaze
  • 2,800
  • 16
  • 20
  • Thanks for all of the effort you put into this answer. I'm working through your solutions and definitely getting closer, but still having issues. I'll mark it as accepted if I can get it to work for me. – BananaNeil Oct 02 '15 at 17:31
  • Are you using a `UISearchDisplayController` or a `UISearchController`? The former was deprecated in iOS 8 and could be the root cause of the issue. – ChrisHaze Oct 02 '15 at 20:16
  • @BananaNeil I've added the code/work that I have implemented outside of just the `viewDidLoad:` method that I supplied originally. – ChrisHaze Oct 02 '15 at 21:01
  • Setting `searchController = hidesNavigationBarDuringPresentation = false` did change the problem to look exactly like the second link you posted, but implementing their solution did not solve my problem. Instead, it turned out that the searchBar *NEEDED* to have a `y` value of `0`. It's super view can be positioned anywhere, but if the searchBar's y position anywhere but 0, this bug persists. – BananaNeil Oct 04 '15 at 18:10
  • I've written an answer with a little more detail, but if you can add the necessity of the `searchController.searchBar.y = 0` to your answer, I'm happy to award your the bounty. – BananaNeil Oct 04 '15 at 18:12
  • @BananaNeil Did you try to set `automaticallyAdjustsScrollViewInsets = NO` on your view controller? This automagical adjustment is often a root of many problems. I never try this with `UISearchDisplayController`, buy it's with to try. – psci Oct 05 '15 at 11:42
  • @psci, that does not work. For some reason, it really needs to be `searchBar.y= 0` – BananaNeil Oct 05 '15 at 16:46
  • 1
    @ChrisHaze Thank you so much for all of your hard work! – BananaNeil Oct 05 '15 at 16:47
6

Not sure if this is iOS 9 specific, but setting

searchController.hidesNavigationBarDuringPresentation = NO;

solves the issue of the weird downward movement of the UISearchBar all over the containing UITableView. Of course, this does disable the nav bar - so this might not be what you want.

Kedar Paranjape
  • 1,822
  • 2
  • 22
  • 33
1

I have actually figured out my issue:

I had my UISearchBar inside of a wrapper view, which I was re-positioning as the UITableView scrolled.

The wrapper was 20px taller than the searchbar, and I set searchbar.y = 20 (for stylistic reasons). Each time I clicked on the search bar, it inexplicably grew by 20px.

At some point, I set the searchBar.y = 10, and noticed that it only grew by 10px.

And sure enough, it turns out that the growth height of the searchBar is exactly equal to it's y-position within it's immediate superview. So, when I set the searchbar.y = 0, the searchbar stopped growing.

BananaNeil
  • 10,322
  • 7
  • 46
  • 66
0

Instead of using a UITableViewController, select a normal UIViewController and add a UITableView to its view. Add constraints to pin it to Top Layout Guide.Bottom, Superview.Leading, Superview.Trailing, Bottom Layout Guide.Top. Then add the Search Bar to the UITableView.

For some reason the Search Bar doesn't jump when implemented this way.

One possible reason could be that while editing the Search Controller adjusts the position of the Search Bar by offsetting the height of the Top Layout Guide. Pinning the Table View top explicitly to Top Layout Guide.Bottom helps somehow.

Hope this helps!

Ishan Handa
  • 2,271
  • 20
  • 25
0

Please try using:

yourSearchBar.clipsToBounds = true
Koby Douek
  • 16,156
  • 19
  • 74
  • 103
0

Swift 5.x solution:

Setting edgesForExtendedLayout to none or empty will fix this issue.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    self.edgesForExtendedLayout = []
}

In the lower versions of swift the usage will be similar to below:

 self.edgesForExtendedLayout = .None
 self.edgesForExtendedLayout = UIRectEdgeNone
Teja Kumar Bethina
  • 3,486
  • 26
  • 34