How to change inside background color of UISearchBar component on iOS

75,554

Solution 1

Use this code to change the searchBar's UITextField backgroundImage:

UITextField *searchField;
NSUInteger numViews = [searchBar.subviews count];
for (int i = 0; i < numViews; i++) {
    if ([[searchBar.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) { //conform?
        searchField = [searchBar.subviews objectAtIndex:i];
    }
}
if (searchField) {
    searchField.textColor = [UIColor whiteColor];
    [searchField setBackground: [UIImage imageNamed:@"yourImage"]]; //set your gray background image here
    [searchField setBorderStyle:UITextBorderStyleNone];
}

Use the below code to change the UISearchBarIcon:

 UIImageView *searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourSearchBarIconImage"]];
searchIcon.frame = CGRectMake(10, 10, 24, 24);
[searchBar addSubview:searchIcon];
[searchIcon release];

Also, to change the searchBar icon you can use the following built-in method on UISearchBar (which is available from iOS 5+):

- (void)setImage:(UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state

Here you can set 4 types of UISearchBarIcon i.e.:

  1. UISearchBarIconBookmark
  2. UISearchBarIconClear
  3. UISearchBarIconResultsList
  4. UISearchBarIconSearch

I hope this help you...

Solution 2

Just customize the text field itself.

I am simply doing this and it works fine for me (iOS 7).

UITextField *txfSearchField = [_searchBar valueForKey:@"_searchField"];
txfSearchField.backgroundColor = [UIColor redColor];

This way you don't need to create an image, size it, etc...

Solution 3

Details

  • Xcode Version 11.0 (11A420a), swift 5

UISearchBar customising sample

Solution

import UIKit

extension UISearchBar {
    func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
    func setTextField(color: UIColor) {
        guard let textField = getTextField() else { return }
        switch searchBarStyle {
        case .minimal:
            textField.layer.backgroundColor = color.cgColor
            textField.layer.cornerRadius = 6
        case .prominent, .default: textField.backgroundColor = color
        @unknown default: break
        }
    }
}

Usage

let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))
//searchBar.searchBarStyle = .prominent
view.addSubview(searchBar)
searchBar.placeholder = "placeholder"
searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))

Result 1

 searchBar.searchBarStyle = .prominent // or default

enter image description here

Result 2

 searchBar.searchBarStyle = .minimal

enter image description here

Full sample

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))
        //searchBar.searchBarStyle = .minimal
        searchBar.searchBarStyle = .prominent
        view.addSubview(searchBar)
        searchBar.placeholder = "placeholder"
        searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
    }
}

Solution 4

Solution which doesn't involve any private API ! :)

Currently (probably since iOS 5 ) you can do this, for simply one colour cases, in this way:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor redColor]];

but please keep in mind that as it basis on appearance the change will be global for the app (it can be an advantage or a disadvantage of the solution).

For Swift you can use (it will work for iOS 9 and above):

if #available(iOS 9.0, *) {
    UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.darkGrayColor()
}

You do not need #available if your project supports iOS 9 and newer.

If you need to support earlier versions of iOS and want to use Swift take a look at this question.

Solution 5

According to the UISearchBar documentation:

You should use this function for iOS 5.0+.

- (void)setSearchFieldBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state

Usage example:

[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];

Sadly, in iOS 4 you need to revert to less sophisticated methods. See other answers.

Share:
75,554
Borut Tomazin
Author by

Borut Tomazin

iOS developer, technology enthusiast and devoted father.

Updated on July 05, 2022

Comments

  • Borut Tomazin
    Borut Tomazin about 2 years

    I know how to remove/change UISearchBar background color around search field:

    [[self.searchBar.subviews objectAtIndex:0] removeFromSuperview];
    self.searchBar.backgroundColor = [UIColor grayColor];
    

    achieved UISearchBar customization

    But don't know how to do this inside it like that:

    desired UISearchBar customization

    This needs to be compatible with iOS 4.3+.

  • Paras Joshi
    Paras Joshi over 11 years
    @BorutTomazin i just add the code for change the textfield backgroundcolor of searchbar and when i get output for search icon i'll also post code hope it help you...
  • Accatyyc
    Accatyyc over 11 years
    This way is not a good way to do it. It can easily break your app in coming iOS updates. EDIT Sorry, just saw that the OP needed it to be compatible with iOS 4.
  • Paras Joshi
    Paras Joshi over 11 years
    @Accatyyc this is give perfact output which he wants and its problem occure in bellow the version of 5.0 or 4.3 so its fine and if you have a solution then post the code dude i have this solution which may useful ...
  • Borut Tomazin
    Borut Tomazin over 11 years
    Yes, this is what I was looking for. Thanks!
  • Borut Tomazin
    Borut Tomazin over 11 years
    This is fine if I am targeting only iOS 5+ devices.
  • iwasrobbed
    iwasrobbed over 10 years
    This would likely be considered using private API, so I'd be cautious submitting an app with this.
  • Yoon Lee
    Yoon Lee over 9 years
    Like @iWasRobbed mentioned, this is using private API that accesses hidden variable through KVC.
  • k06a
    k06a about 9 years
    SearchBarStyle should be default! :)
  • Legoless
    Legoless about 9 years
    This doesn't work for me, not even on default or minimal style (iOS 8).
  • Julian
    Julian almost 9 years
    @iWasRobbed and please take a look at my answer, maybe that will be fine for you
  • Mahmoud Adam
    Mahmoud Adam almost 9 years
    sorry @JulianKról I just saw your answer now, didn't notice it before
  • Julian
    Julian almost 9 years
    no problem, just noticed yours, and checked how it is different :)
  • Max MacLeod
    Max MacLeod over 8 years
    Works but iOS 9 only. Here is the Swift equivalent: UITextField.appearanceWhenContainedInInstancesOfClasses([UIS‌​earchBar.self]).back‌​groundColor = UIColor.darkGrayColor()
  • Max MacLeod
    Max MacLeod over 8 years
    duplicates previous answer
  • Julian
    Julian over 8 years
    @MaxMacLeod, thanks I have updated my answer based on what you posted
  • TheCodingArt
    TheCodingArt over 8 years
    cough this can be rejected from Apple because you're accessing private variables cough
  • jose920405
    jose920405 over 8 years
    Still Working in the last ios version
  • Ivan
    Ivan almost 8 years
    This had no effect for me. But setting the textField.layer.backgroundColor does change the background color.
  • Nubaslon
    Nubaslon almost 8 years
    Best and simple solution! Thnx! =)
  • tanya
    tanya over 7 years
    This was killing me...thanks for pointing out that for minimal you had to do layer.backgroundColor...
  • EmilDo
    EmilDo over 7 years
    One interesting problem with this solution is that when type is .minimal and one sets the background to white -> the background becomes grey. this is due to the fact that the top of the view is taken by an image named _UISearchBarSearchFieldBackgroundView
  • Vasily  Bodnarchuk
    Vasily Bodnarchuk over 7 years
    Can't understand. Can you show the code? I have no problem with setting searchBar.backgroundColor = .white.
  • Tim Friedland
    Tim Friedland almost 7 years
    Beautiful solution! Thank you.
  • Benjamin Wen
    Benjamin Wen almost 7 years
    This is surely the best and the most graceful way. Thanks! Saved my life.
  • Benjamin Wen
    Benjamin Wen almost 7 years
    For guys looking for a better solution, I recommend you read EvGeniy Ilyin's, which is way bellow the many ugly solutions. (cmd+F, search this page.) UISearchBar.appearance().setSearchFieldBackgroundImage(white‌​Image, for: .normal)
  • Benjamin Wen
    Benjamin Wen almost 7 years
    not the best solution. see EvGeniy Ilyin's, which is way bellow the many ugly solutions. (cmd+F, search this page.) UISearchBar.appearance().setSearchFieldBackgroundImage(white‌​‌​Image, for: .normal)
  • coolcool1994
    coolcool1994 almost 7 years
    iOS 11 for minimal searcher, setting .layer background doesn't work anymore. It seems there is an additional view on top of the textfield.
  • Greg Brown
    Greg Brown over 6 years
    It doesn't use private API but it still relies on private implementation details (i.e. the internal view hierarchy of the search bar). This implementation could change at any time.
  • Jbryson
    Jbryson about 6 years
    This is the correct way. I was just about to post a version of this. Good work! Very Complete!
  • Yogesh Patel
    Yogesh Patel over 5 years
    why we use layer for minimal searchBarStyle .? because when I remove backgroundColor without layer it not set the color that's why .
  • btomtom5
    btomtom5 over 5 years
    Maybe I am doing something wrong, but this sets the background image of the entire search bar and not the just the background image inside the text field
  • Partho63
    Partho63 over 5 years
    Pleas don't just put some code, provide some explanation also.
  • Vasily  Bodnarchuk
    Vasily Bodnarchuk almost 5 years
    @ApoorvKhatreja it is possible. I will wait for the official Xcode release and then update the code.
  • Funnycuni
    Funnycuni over 4 years
    how to you change the place holder text color for iOS 13 ?
  • whyoz
    whyoz over 4 years
    in iOS 13: Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug' .. this is now going to cause app crashes, so you should change the solution to continue getting upvotes!
  • Merricat
    Merricat over 4 years
    Finally a solution that doesn't use the private API! I went with UISearchBar.appearance().setSearchFieldBackgroundImage(UIIma‌​ge(), for: .normal) to completely remove the grey image
  • donjuedo
    donjuedo over 4 years
    iOS 13 gives me: reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug'
  • andygeers
    andygeers almost 4 years
    Although in iOS 13 onwards there is a public API _searchBar.searchTextField