17

I am building an iOS 7-only app. I am trying to set a UISearchDisplayController into the navigation bar.

I have it set up like this: In the storyboard, I added a "Search Bar and Search Display Controller" to my view controller's view, and set it at (0,0) relative to the top layout guide. I set constraints to pin to left, top and right. (I played with the constraints, i removed them completely, it doesn't matter) On top of that I have my Table view. When I added the search bar to the view in the storyboard, it automatically setup outlets for searchDisplayController and searchBar delegate. In code I have self.searchDisplayController.displaysSearchBarInNavigationBar = YES; I have two problems:

1) Without any buttons showing for the search bar (Interface builder -> select search bar -> Options: none selected) the search bar is in the middle of the screen:

enter image description here

If I click on the navigation bar, it starts editing the search bar:

enter image description here

notice also that the dark overlay appears to be offset from the navigation bar. It seems to me that the space is the same height as the navigation bar. Like it has been shifted down by that much. Also, when it displays the search results, the top of the content view is shifted down by the same amount (more pictures follow), which brings me to the second problem.

2) I messed around with it for a while and decided to check the option to have it show the cancel button. Now I have the search bar embedded in the nav bar correctly, but the overlay is still shifted down:

enter image description here

Again, when the search results table view appears, it is shifted down by the same amount (notice the scroll bar on the right side):

enter image description here

Even more bizarrely, I set a border on the search display controller's tableview layer, and it appears correct:

enter image description here

I have never used the UISearchDisplayController before and I unfamiliar with how to set it up, but functionally it works fine. I have read some other similar posts but the only advice is to hack it up by adjusting frames and setting manual offsets. I'd prefer to know what is causing this, is it a bug? Something I'm doing wrong? If it's a bug I can wait for a fix. It seems like such a basic thing that a thousand people must have done without any problem so I feel like I'm not setting it up correctly somehow. Thanks for you input.

rmaddy
  • 298,130
  • 40
  • 468
  • 517
d370urn3ur
  • 1,667
  • 3
  • 17
  • 22

9 Answers9

29

I remember running into the same exact problem that you are observing.There could be a couple of solutions you can try.

  • If you are using storyboards You should click on the view controller or TableView Controller which you have set up for your tableview and go to its attribute inspector and look under ViewController section and set the Extend Edges section to be under Top Bars.

  • If you are not using storyboards you can manually set the settings using the viewcontrollers edgesForExtendedLayout property and that should do the trick. I was using storyboards.

hackamanshu
  • 376
  • 3
  • 5
  • thanks, that worked. I still wish I could figure out why the search bar doesn't work without the cancel button, but this is close enough – d370urn3ur Jan 04 '14 at 10:30
  • I have it working without the Cancel Button, what exactly is happening when you don't add the Cancel button. – hackamanshu Jan 04 '14 at 20:06
  • if you look at the 1st and 2nd pictures in my question you can see it. Basically, with the cancel button, the search bar embeds correctly in the nav bar. Without the cancel button, the search bar is displaced to the center of the screen, on top of the table view – d370urn3ur Jan 06 '14 at 09:34
  • Ok, I simply added the SearchBar with SearchDisplay Controller to my viewController (didn't touch constraints at all) and I don't think you need to set origin to (0,0) since the searchBar will be living on the navigationBar. Also, to me it looks like an autolayout issue. Try unchecking the autolayout option for the View Controller in the File Inspector to see if the behavior changes. – hackamanshu Jan 06 '14 at 19:05
  • 3
    it's strange, I finally got it to work by removing the searchbar with searchdisplay controller from the viewcontroller's view and placing it OUTSIDE the view hierarchy completely. I've never done that before, but it worked. That also had the added effect of adding some kind of automatic padding to the table view so that it is placed below the nav bar. Otherwise, I have to add the padding myself (64px) to offset the nav bar. – d370urn3ur Jan 08 '14 at 18:34
  • I think its because you must have been using a UITableViewController and therefore putting the SearchBar inside the View hierarchy was causing concerns. Well I'm glad you got it working :) – hackamanshu Jan 08 '14 at 21:42
  • 3
    Also don't forget to see if extendedLayoutIncludesOpaqueBars is applicable for your specific situation. – Cedrick Nov 23 '15 at 13:57
  • 2
    if your navigationbar is set to opaque, tick the 'extend under opaque bars' as well. – nsuinteger Mar 17 '16 at 04:50
17

In my case, using storyboards, I had to check both Under Top Bars and Under Opaque Bars and leave Under Bottom Bars unchecked.

Gerhat
  • 741
  • 1
  • 7
  • 13
3

In my case, I actually had to uncheck all the Extended Edges boxes (essentially the same as programmatically setting Extended Edges to UIRectEdgeNone I believe) in my Storyboard in order to stop my search bar from offsetting itself. Thank you guys!

Danchez
  • 865
  • 1
  • 8
  • 26
2

definesPresentationContext = true

override func viewDidLoad() {
        super.viewDidLoad()

        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false

        searchController.dimsBackgroundDuringPresentation = true
        searchController.searchBar.searchBarStyle = UISearchBarStyle.Prominent
        self.tableView.tableHeaderView = searchController.searchBar

        definesPresentationContext = true

or see UISearchBar presented by UISearchController in table header view animates too far when active

Community
  • 1
  • 1
Gleb
  • 370
  • 2
  • 9
2

My problem was just Adjust scroll view inserts. After change to false I didn't have problem

1

I had a same problem. And I solve this issue with adding view object under the tableview.

  1. Add new ViewController on the Storyboard
  2. Drag TableView to the new VC
  3. Drag Table Cell to the TableView
  4. Make a Connection for TableView DataSource, TableView Delegate to the new VC
dakeshi
  • 11
  • 1
1

I had very similar behavior happening. For me, the solution was to uncheck Extend Edges Under Top Bar in the storyboard settings for the parent view controller (I've turned off transparent navbars, not sure if that effects anything). If you're not using storyboard, you have to set [UIViewController edgesForExtendedLayout].

From the Apple docs:

This property is only applied to view controllers that are embedded in containers, such as UINavigationController or UITabBarController. View controllers set as the root view controller do not react to this property. Default value is UIRectEdgeAll.

Alex Sharp
  • 524
  • 5
  • 12
0

Unfortunately none of the above solutions worked for me, I'm using a UITableViewController.

This link helped:

http://petersteinberger.com/blog/2013/fixing-uisearchdisplaycontroller-on-ios-7/

I put the code below for convenience:

static UIView *PSPDFViewWithSuffix(UIView *view, NSString *classNameSuffix) {
    if (!view || classNameSuffix.length == 0) return nil;

    UIView *theView = nil;
    for (__unsafe_unretained UIView *subview in view.subviews) {
        if ([NSStringFromClass(subview.class) hasSuffix:classNameSuffix]) {
            return subview;
        }else {
            if ((theView = PSPDFViewWithSuffix(subview, classNameSuffix))) break;
        }
    }
    return theView;
}

- (void)correctSearchDisplayFrames {
    // Update search bar frame.
    CGRect superviewFrame = self.searchDisplayController.searchBar.superview.frame;
    superviewFrame.origin.y = 0.f;
    self.searchDisplayController.searchBar.superview.frame = superviewFrame;

    // Strech dimming view.
    UIView *dimmingView = PSPDFViewWithSuffix(self.view, @"DimmingView");
    if (dimmingView) {
        CGRect dimmingFrame = dimmingView.superview.frame;
        dimmingFrame.origin.y = self.searchDisplayController.searchBar.frame.size.height;
        dimmingFrame.size.height = self.view.frame.size.height - dimmingFrame.origin.y;
        dimmingView.superview.frame = dimmingFrame;
    }
}

- (void)setAllViewsExceptSearchHidden:(BOOL)hidden animated:(BOOL)animated {
    [UIView animateWithDuration:animated ? 0.25f : 0.f animations:^{
        for (UIView *view in self.tableView.subviews) {
            if (view != self.searchDisplayController.searchResultsTableView &&
                view != self.searchDisplayController.searchBar) {
                view.alpha = hidden ? 0.f : 1.f;
            }
        }
    }];
}

// This fixes UISearchBarController on iOS 7. rdar://14800556
- (void)correctFramesForSearchDisplayControllerBeginSearch:(BOOL)beginSearch {
    if (PSPDFIsUIKitFlatMode()) {
        [self.navigationController setNavigationBarHidden:beginSearch animated:YES];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self correctSearchDisplayFrames];
        });
        [self setAllViewsExceptSearchHidden:beginSearch animated:YES];
        [UIView animateWithDuration:0.25f animations:^{
            self.searchDisplayController.searchResultsTableView.alpha = beginSearch ? 1.f : 0.f;
        }];
    }
}

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
    [self correctFramesForSearchDisplayControllerBeginSearch:YES];
}

- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
    [self correctSearchDisplayFrames];
}

- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
    [self correctFramesForSearchDisplayControllerBeginSearch:NO];
}

- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
    // HACK: iOS 7 requires a cruel workaround to show the search table view.
    if (PSPDFIsUIKitFlatMode()) {
        controller.searchResultsTableView.contentInset = UIEdgeInsetsMake(self.searchDisplayController.searchBar.frame.size.height, 0.f, 0.f, 0.f);
    }
}
KVISH
  • 12,097
  • 15
  • 79
  • 151
0
  1. Go to storyboard.
  2. Click on the view controller.
  3. Go to attribute inspector under the ViewController section.
  4. Set the Extend Edges section to be Under Top Bars and Under Opaque Bars.
  5. Make sure to un-check Under Bottom Bars.
Rann Lifshitz
  • 3,862
  • 4
  • 18
  • 40