UISearchBar: clear background color or set background image [duplicate]
Asked Answered
T

13

41

How can set the background image, or clear the background, of a search bar, like the note application?

Torosian answered 26/1, 2010 at 11:46 Comment(1)
self.searchBar.setSearchFieldBackgroundImage(UIImage(), for: .normal)Mota
M
8

I just came up with a solution that works really well. You have to override the UISearchBar and then hide both the Background and Segment Control layers. Then Draw the background.

@ .m

#import "UISearchBar.h" 
#import <QuartzCore/QuartzCore.h>

@implementation UISearchBar(CustomBackground)

- (id)init
    {
        for ( UIView * subview in self.subviews ) 
        {
            if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground") ] ) 
                subview.alpha = 0.0;  

            if ([subview isKindOfClass:NSClassFromString(@"UISegmentedControl") ] )
                subview.alpha = 0.0; 
        } 

        return self;
    }

+ (UIImage *) bgImagePortrait
    {
        static UIImage *image = nil;
        if (image == nil)
            image = [[UIImage imageNamed:@"UISearchBarBack.png"] retain ];

        return image;
    }

+ (UIImage *) bgImageLandscape
    {
        static UIImage *image = nil;
        if (image == nil)
            image = [[UIImage imageNamed:@"UISearchBarBack.png"] retain];

        return image;
    }

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)contenxt
    {
        if ([self isMemberOfClass:[UISearchBar class]] == NO)
            return; 

        UIImage * image = ( self.frame.size.width > 320 ) ? [UISearchBar bgImageLandscape ] : [UISearchBar bgImagePortrait ];  

        for ( UIView * subview in self.subviews ) {
            if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground") ] ) 
                subview.alpha = 0.0; 

            if ([subview isKindOfClass:NSClassFromString(@"UISegmentedControl") ] )
                subview.alpha = 0.0; 
        }

        CGContextTranslateCTM( contenxt , 0 , image.size.height );
        CGContextScaleCTM( contenxt, 1.0, -1.0 );
        CGContextDrawImage( contenxt , CGRectMake( 0 , 0 , image.size.width , image.size.height ), image.CGImage );
    }  

@end

@ .h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>


@interface UISearchBar(CustomBackground) 

@end

Hope this helps!

Malaco answered 5/4, 2011 at 19:18 Comment(2)
Doesn't work for me... (ios 4.2)Passant
Also does not work for me on iOS 5Chon
A
175

A future-proof way:

[searchBar setBackgroundImage:[UIImage new]];
[searchBar setTranslucent:YES];
Angeliqueangelis answered 26/9, 2012 at 9:34 Comment(11)
Working on ios 5 & ios 6 as well. Tested on IPadJeffreys
Great, but : [UIImage new] is equivalent to [[UIImage alloc] init]. Your image is never released. > Do [searchBar setBackgroundImage:[[UIImage new]autorelease]];Fries
it's released for you if you use ARC though.Proviso
Martin no! Use ARC dammit. Unless you need super performant code, even then I'm not convinced ARC wont be better for most situations.Conics
This is the best answer if you ask me. It works perfectly, and is so clean and simple. Now, let's just see what iOS7 brings :)Supercharge
Confirmed this works with iOS 7Fults
this does not work in iOS7.Oarsman
Confirmed working in iOS 7.1 for UISearchBars with SearchBarStyle UISearchBarStyleProminentWillardwillcox
This works but be warned - it causes a bug: if you have a refresh control it will lie overtop the search bar instead of rendering underneath it when the two overlap.Hyperbola
works ios8 couldn't be easier!!Oza
Works under iOS9 even without setting it to translucentDislocate
P
29

mj_ has the answer that i used. i was just going to comment as such but i can't yet. So i'll just post my own answer with my implementation where I add a search bar to the top of a table view with a semi-transparent BG.

DLog(@"    Add search bar to table view"); 

//could be a UIImageView to display an image..?
bg = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)] autorelease];
bg.backgroundColor        = [UIColor blackColor];
UISearchBar *sb           = [[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 290, 45)] autorelease];
sb.barStyle               = UIBarStyleBlackTranslucent;
sb.showsCancelButton      = NO;
sb.autocorrectionType     = UITextAutocorrectionTypeNo;
sb.autocapitalizationType = UITextAutocapitalizationTypeNone;
sb.delegate               = self;
[bg addSubview:sb];
table.tableHeaderView     = bg;

for (UIView *subview in sb.subviews) {
    if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
        [subview removeFromSuperview];
        break;
    }
}   
Phosphorate answered 3/10, 2010 at 4:44 Comment(5)
+1 for still being accurate in 2011. I was looking for the last five lines of your example. Cheers!Eyestrain
if you use an uiimageview to display a backgroundimage and you want to hide the searchbar behind the navigationbar, the image needs to be 44 px height. Or use clipsToBounds = YES, otherwise there will be a 1 px line drawn under the navigationbar.Betrothed
I did like this: NSClassFromString([NSString stringWithFormat:@"U%@Sea%@", @"I", @"rchBarBackground"]) in case apple would search for strings naming their private class.. but don't know if it would help(?)Preface
Will Apple reject this code because it's using private class "UISearchBarBackground"?Hula
I used this in an application that was submitted to the app store and it was not rejected.Phosphorate
P
14

I had problems w/ the answer above. I used the following.

for (UIView *subview in searchBar.subviews) {
    if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
        [subview removeFromSuperview];
        break;
    }
}
Prink answered 24/9, 2010 at 14:12 Comment(4)
As of SDK 4.2, this breaks the buttons and fields.Bromley
I'm wrong, it only does that if you put this code in layoutSubviews. Duh.Bromley
Don't forget to set your color after for cycle - [searchBar setBackgroundColor:[UIColor clearColor]];Impiety
This approach does not work in Xcode 4.4.1 on iOS 5.1.Flow
P
12

This worked for me (ios4.2+)

// Change the search bar background
-(void)viewWillAppear:(BOOL)animated {
    for (UIView *subview in self.searchBar.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
            UIView *bg = [[UIView alloc] initWithFrame:subview.frame];
            bg.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"search_bar_bg"]];
            [self.searchBar insertSubview:bg aboveSubview:subview];
            [subview removeFromSuperview];
            break;
        }
    }   
}
Passant answered 29/5, 2011 at 22:59 Comment(0)
M
8

I just came up with a solution that works really well. You have to override the UISearchBar and then hide both the Background and Segment Control layers. Then Draw the background.

@ .m

#import "UISearchBar.h" 
#import <QuartzCore/QuartzCore.h>

@implementation UISearchBar(CustomBackground)

- (id)init
    {
        for ( UIView * subview in self.subviews ) 
        {
            if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground") ] ) 
                subview.alpha = 0.0;  

            if ([subview isKindOfClass:NSClassFromString(@"UISegmentedControl") ] )
                subview.alpha = 0.0; 
        } 

        return self;
    }

+ (UIImage *) bgImagePortrait
    {
        static UIImage *image = nil;
        if (image == nil)
            image = [[UIImage imageNamed:@"UISearchBarBack.png"] retain ];

        return image;
    }

+ (UIImage *) bgImageLandscape
    {
        static UIImage *image = nil;
        if (image == nil)
            image = [[UIImage imageNamed:@"UISearchBarBack.png"] retain];

        return image;
    }

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)contenxt
    {
        if ([self isMemberOfClass:[UISearchBar class]] == NO)
            return; 

        UIImage * image = ( self.frame.size.width > 320 ) ? [UISearchBar bgImageLandscape ] : [UISearchBar bgImagePortrait ];  

        for ( UIView * subview in self.subviews ) {
            if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground") ] ) 
                subview.alpha = 0.0; 

            if ([subview isKindOfClass:NSClassFromString(@"UISegmentedControl") ] )
                subview.alpha = 0.0; 
        }

        CGContextTranslateCTM( contenxt , 0 , image.size.height );
        CGContextScaleCTM( contenxt, 1.0, -1.0 );
        CGContextDrawImage( contenxt , CGRectMake( 0 , 0 , image.size.width , image.size.height ), image.CGImage );
    }  

@end

@ .h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>


@interface UISearchBar(CustomBackground) 

@end

Hope this helps!

Malaco answered 5/4, 2011 at 19:18 Comment(2)
Doesn't work for me... (ios 4.2)Passant
Also does not work for me on iOS 5Chon
M
8

You have two questions here:
1.UISearchBar clear background color:
See my answer here

2.Set background image Solution:(If you are in iOS 5.0 +)

[[UISearchBar appearance]setSearchFieldBackgroundImage:[navBarGradImage resizableImageWithCapInsets:inset2] forState:UIControlStateNormal];

NOTE: You can also try using a transparent image as a background.

Hope this helps.

Mapp answered 18/5, 2012 at 6:10 Comment(0)
C
4

I prefer to just set the alpha to 0 so you can hide/show on demand.

// Hide
[[self.theSearchBar.subviews objectAtIndex:0] setAlpha:0.0];

// Show
[[self.theSearchBar.subviews objectAtIndex:0] setAlpha:1.0];
Composite answered 15/3, 2012 at 21:32 Comment(1)
This does not work in Xcode 4.4.1.Flow
L
4

How to set background color in UISearchBar:

#import <QuartzCore/QuartzCore.h>

Then make an outlet connection to search bar (say, objSearchbar), and use these lines :

for (UIView *subview in self.objSearchbar.subviews) 
{
    if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) 
    {
        [subview removeFromSuperview];
        break;
    }
}

self.tweetSearchbar.layer.backgroundColor = [UIColor blueColor].CGColor;
Lothaire answered 28/3, 2012 at 15:41 Comment(1)
this thing is working fine for me. +1 rated.Impeccant
W
4

searchBar.searchBarStyle = UISearchBarStyleMinimal;

Wellfound answered 3/2, 2014 at 21:8 Comment(0)
S
2

Look here: UISearchbar background image change

Shivaree answered 27/3, 2010 at 11:33 Comment(0)
A
2

with iOS8 sdks apple moved @"UISearchBarBackground" view one level deeper, so have will need to look at subviews of the child-views as bellow,

for (UIView *subview in searchBar.subviews) {
        for(UIView* grandSonView in subview.subviews){
            if ([grandSonView isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
                grandSonView.alpha = 0.0f;
            }else if([grandSonView isKindOfClass:NSClassFromString(@"UISearchBarTextField")] ){
                NSLog(@"Keep textfiedld bkg color");
            }else{
                grandSonView.alpha = 0.0f;
            }
        }//for cacheViews
    }//subviews
Amass answered 11/12, 2014 at 11:30 Comment(0)
U
1

Set background image

    UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:searchBar.bounds];
    backgroundView.image = [UIImage imageNamed:@"xxxx.png"];
    [searchBar insertSubview:backgroundView atIndex:1]; // at index 1 but not 0
    [backgroundView release];
Uxorial answered 21/9, 2011 at 8:46 Comment(0)
D
0

One liner:

[[self.theSearchBar.subviews objectAtIndex:0] removeFromSuperview];
Dad answered 18/10, 2011 at 5:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.