How to Get Rid of UISearchBar’s Background and Customize its SearchField’s Background

It is quite widely admitted that a lot of UI components on iOS 6.1 and previous are a pain to customize. Apple did add the ability to use appearance in order to modify the more cumbersome elements, such as UINavigationBar and UINavigationItem, but there are still some elements that are not easily dealt with, especially on Xcode versions older than 5.

Today, I’m going to show you how I managed to get rid of all of UISearchBar’s backgrounds, so that I could use it above anything without setting its background (which can be ok in some cases, but is not always what we are looking for).

Customizing a UISearchBar

Classic UISearchBar
The classic look of UISearchBar

Every iOS developer probably has some awful memories of him struggling with tint color and background colors or images, and finally giving up and just doing something that was not so bad, but clearly not perfect (either by capitulating and using tint, or by simply not using UISearchBar at all and reinventing the wheel). The thing is, with UISearchBar, that setting its background color does nothing, and setting its tint does not remove its gradient. However, setting its background image works quite well.

The idea here is to use the background image to get what we want from UISearchView. Assuming you’ve created your UISearchView either in code, either in a xib and linked it properly in the header file, here’s what you should do :


- (void)viewDidLoad
{
    [super viewDidLoad];
    // 1
    UIImage* clearImg = [CDViewController imageWithColor:[UIColor clearColor] andHeight:32.0f];
    // 2
    [_searchBar setBackgroundImage:clearImg];
    // 3
    [_searchBar setSearchFieldBackgroundImage:clearImg forState:UIControlStateNormal];
    // 4
    [_searchBar setBackgroundColor:[UIColor clearColor]];
}

+ (UIImage*) imageWithColor:(UIColor*)color andHeight:(CGFloat)height
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

There are multiple things going on here :

1/ We create an image of size 1×32 filled with clear color. At first I tried with a 1×1 image, but quickly realized that when set on the searchField, it is only stretched horizontally, and will simply make the text in the UISearchBar disappear, except for that 1px line where our background is.

2/ We set this image as the background of our UISearchBar.

3/ We set this image as the background of the searchField.

4/ We set the background color of the SearchBar to clearColor.

Also, it could be a good idea to have the imageWithColor:andHeight: function in a category on UIImage, ready to be used anywhere in your project !

clearColor background UISearchBar
Here is the result of this operation

As you can see, we do not really emphasize the fact that it is a textField area anymore. To solve this problem, we have multiple options. We can set the color of _searchBar’s background to anything other than clearColor, but that would mean that it’s height would be stuck at 44. More flexible options would be to either put a colored view of the size we desire behind our UISearchBar, or, if we don’t want to add much more code, to set a colored 1x32px (or any height you wish it to take) UIImage as a background for the searchField :

Our customized UISearchBar
Here is what the customized UISearchBar looks like after our changes

Set as default appearance

In order to make this the default for all the application’s UISearchBars, let’s leverage the power of [UISearchBar appearance], by calling all this in our app delegate, for exemple :


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIColor* myColor = [UIColor colorWithRed:0 green:0.48 blue:1 alpha:1]; // set your desired background color here

    UIImage* clearImg = [CDViewController imageWithColor:[UIColor clearColor] andHeight:1.0f];
    UIImage* coloredImg = [CDViewController imageWithColor:myColor andHeight:32.0f];

    [[UISearchBar appearance] setBackgroundColor:[UIColor clearColor]];
    [[UISearchBar appearance] setBackgroundImage:clearImg];
    [[UISearchBar appearance] setSearchFieldBackgroundImage:coloredImg forState:UIControlStateNormal];

    return YES;
}

And voilà ! Off you go with your new shiny toy !

Notes

When I wrote this, I encountered less problems than when I tried to solve this matter in the first place. In fact, when adding the UISearchBar, I checked “Show Scope Bar” in Interface Builder, before unchecking it. Doing so automatically adds a segmented control with two buttons who’s titles are “title”. Pay attention to it and delete them if you don’t need to use the Scope Bar, otherwise it’d mess your work.

Here’s, using Spark Inspector, the content of your UISearchBar if you showed/hided the Scope Bar by mistake.

UISearchBar with hidden Scope Bar in Spark  Inspector
UISearchBar with hidden Scope Bar in Spark Inspector

We can see the segmented control, right behind our UISearchBar’s background and searchField’s background. Now, if you want to have no background behind your UISearchBar *and* use the Scope Bar for whatever reason, here’s what you should be doing in order to hide it.


UIImage* clearImg = [CDViewController imageWithColor:[UIColor clearColor] andHeight:1.0f];

[_searchBar setScopeButtonTitles:nil];
[_searchBar setScopeBarBackgroundImage:clearImg];
[_searchBar setScopeBarButtonBackgroundImage:clearImg forState:UIControlStateNormal];
[_searchBar setScopeBarButtonDividerImage:clearImg forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal];

I hope this’ll help someone out there. Please leave a commentary if you found some use to my code, or if you have a remark or question about it ! 😉

This post is also available in: French

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.