11

I want my search bar to draw its background extended upwards below the status bar like this:

enter image description here

This is the corresponding code for the image above:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.searchBar = [[UISearchBar alloc] init];
    self.searchBar.delegate = self;
    [self.view addSubview:self.searchBar];
    
    self.searchBar.translatesAutoresizingMaskIntoConstraints = NO;
    NSDictionary *views = @{@"v":self.searchBar,
                            @"topLayoutGuide":self.topLayoutGuide};
    
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide][v]" options:0 metrics:nil views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]|" options:0 metrics:nil views:views]];
    
    [self.searchBar setBackgroundImage:[UIImage imageNamed:@"searchbarBG"] forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefault];
}

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
    return UIBarPositionTopAttached;
}

The problem arises when I add the search bar to a UISearchDisplayController by appending the following line at the end of the viewDidLoad method:

self.mySearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];

This is the result I get:

enter image description here

Note that the image looks clipped. This is different from what it looks like if I change UIBarPositionTopAttached to UIBarPositionTop in the code:

enter image description here

The image being clipped made me think of clipsToBounds and I could get the search bar to display properly by adding this piece of code at the end of viewDidLoad:

for (UIView *subview in self.searchBar.subviews) {
    subview.clipsToBounds = NO;
}

So I guess the UISearchDisplayController is messing with the clipsToBounds property of the UISearchBar background view. Has anyone else struggled with this? Is there a problem with my code?

Update:

Back in October 2013, besides posting this question, I also reported this using the Apple Bug Reporter tool. On January 6, 2015 (waaaay too late) I got a reply from Apple Developer Relations:

There are no plans to address this based on the following:

UISearchDisplayController is no longer supported. The desired functionality should be available with UISearchController and if not (or is behaving incorrectly), please file a new bug.

We are now closing this report.

If you have questions about the resolution, or if this is still a critical issue for you, then please update your bug report with that information.

Please be sure to regularly check new Apple releases for any updates that might affect this issue.

Community
  • 1
  • 1
albertamg
  • 28,492
  • 6
  • 64
  • 71
  • 1
    This was very helpful, thank you! In my case, a UITableViewController was involved and adding `self.tableView.clipToBounds = NO` solved it (although I'm not sure it's a good thing to do perf-wise so I'm only doing it when the search bar is activated) – Clafou Mar 26 '14 at 20:45

2 Answers2

3

I was having the exact same issue, but forcing clipsToBounds to YES for the searchBar, did the trick. No need of auto-layout nor UIBarPositioning protocol methods.

DZenBot
  • 4,806
  • 2
  • 25
  • 27
0

You conform to the UIBarPositioningDelegate protocol and upon properly becoming the delegate for your SearchBar, implement the delegate method as such

-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }

Matt
  • 1,599
  • 14
  • 14
  • My mistake. I have used it for bars placed in the storyboard with 20pt offset in iOS 7. I assumed it would work for your bar too. btw is the delegate being called for your search bar? – Matt Jan 07 '14 at 09:41
  • Yes, it is. The problem only arises when I add the search bar to a `UISearchDisplayController`. – albertamg Jan 07 '14 at 10:07