How to customize the searchBar in a UISearchController?

16,677

Solution 1

set attributedPlaceholder for textfield of search bar

@IBOutlet weak var sbSearchBar: UISearchBar!
if let textfield = sbSearchBar.value(forKey: "searchField") as? UITextField {

    textfield.backgroundColor = UIColor.red
    textfield.attributedPlaceholder = NSAttributedString(string: textfield.placeholder ?? "", attributes: [NSAttributedStringKey.foregroundColor : UIColor.white])

    if let leftView = textfield.leftView as? UIImageView {
        leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
        leftView.tintColor = UIColor.white
    }

}

Here is result:

enter image description here

Update:

I think, this may help you: how to change uitextfield color in searchcontroller?

Just apply your color combination in this code and see.

if #available(iOS 11.0, *) {
            let sc = UISearchController(searchResultsController: nil)
            sc.delegate = self
            let scb = sc.searchBar
            scb.tintColor = UIColor.white
            scb.barTintColor = UIColor.white


            if let textfield = scb.value(forKey: "searchField") as? UITextField {
                //textfield.textColor = // Set text color
                if let backgroundview = textfield.subviews.first {

                    // Background color
                    backgroundview.backgroundColor = UIColor.white

                    // Rounded corner
                    backgroundview.layer.cornerRadius = 10;
                    backgroundview.clipsToBounds = true;

                }
            }

            if let navigationbar = self.navigationController?.navigationBar {
                navigationbar.barTintColor = UIColor.blue
            }
            navigationItem.searchController = sc
            navigationItem.hidesSearchBarWhenScrolling = false

}

Result:

enter image description here

Solution 2

Add the following with your code in viewDidAppear:

            let placeholderString = NSAttributedString(string: "Placeholder", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
            field.attributedPlaceholder = placeholderString

            let iconView = field.leftView as! UIImageView
            iconView.image = iconView.image?.withRenderingMode(.alwaysTemplate)
            iconView.tintColor = .white

Update - the following is the complete code to customize UISearchController colors:

override func viewDidAppear(_ animated: Bool) {

    //sets navigationbar backgroundColor
    if let navigationbar = self.navigationController?.navigationBar {
        navigationbar.barTintColor = UIColor.magenta
    }

    let searchField = searchController.searchBar.value(forKey: "searchField") as? UITextField

    //sets searchBar backgroundColor
    searchController.searchBar.backgroundColor = .blue

    if let field = searchField {
        field.layer.cornerRadius = 15.0
        //sets text Color
        field.textColor = .brown

        //sets indicator and cancel button Color
        field.tintColor = .green

        field.font = UIFont.systemFont(ofSize: 13)
        field.layer.masksToBounds = true
        field.returnKeyType = .search

        //sets placeholder text Color
        let placeholderString = NSAttributedString(string: "placeholder", attributes: [NSAttributedStringKey.foregroundColor: UIColor.red])
        field.attributedPlaceholder = placeholderString

        //sets icon Color
        let iconView = field.leftView as! UIImageView
        iconView.image = iconView.image?.withRenderingMode(.alwaysTemplate)
        iconView.tintColor = .cyan

        //sets textField backgroundColor
        if let backgroundview = field.subviews.first {
            backgroundview.backgroundColor = UIColor.yellow
        }
    }
}

Solution 3

The accepted solution does not work for iOS 13, you are getting the following error (testet with Obj-C Code):

Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug'

But now you have the option to access UISearchBar's TextField directly, without using a private API.

if (@available(iOS 13, *)) {
        self.searchController.searchBar.searchTextField.backgroundColor = [UIColor whiteColor];
        self.searchController.searchBar.searchTextField.tintColor = [UIColor darkGrayColor];
    }
    else {
        UITextField *txfSearchField = [self.searchController.searchBar valueForKey:@"_searchField"];
        UIView *background = txfSearchField.subviews.firstObject;
        background.layer.cornerRadius = 10;
        background.clipsToBounds = true;
        background.backgroundColor=[UIColor whiteColor];

        txfSearchField.tintColor=[UIColor darkGrayColor];
        txfSearchField.textColor = [UIColor redColor];
    }
Share:
16,677
JsW
Author by

JsW

Updated on June 04, 2022

Comments

  • JsW
    JsW almost 2 years

    I know how to set the appearance for a independent UISearchBar, just like the following.

        let searchField = searchBar.value(forKey: "searchField") as? UITextField
    
        if let field = searchField {
            field.backgroundColor = UIColor.defaultBackgroundColor
            field.layer.cornerRadius = 15.0
            field.textColor = .white
            field.tintColor = .white
    
            field.font = UIFont.systemFont(ofSize: fl(13))
            field.layer.masksToBounds = true
            field.returnKeyType = .search
        }
    

    But this is not working in the UISearchController.

    enter image description here

    I want to set the text color of the placeholder and the left magnifying lens icon to pure white. (It seems there is a colored layer over them now).

    In addition, the input text is black now, I want it to be white too.

    In a conclusion, I want to modify the following properties.
    1. textField background color
    2. textFiled placeholder text color
    3. textFiled text color
    4. textFiled font

    Anyone know how do it?

    Add the following with your code in viewDidAppear:

                let placeholderString = NSAttributedString(string: "Placeholder", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
                field.attributedPlaceholder = placeholderString
    
                let iconView = field.leftView as! UIImageView
                iconView.image = iconView.image?.withRenderingMode(.alwaysTemplate)
                iconView.tintColor = .white
    

    Updata:
    Put those settings in ViewDidAppear() did solve a part of my problem.
    But the textfield's background color changed when I set the bar's background color.
    Because searchBar.barTintColor = .red is not working in iOS11's UISearchController embedded in navigation item, I used searchBar.backgroundColor = .red
    It confused me a lot.
    So how to change searchBar's background and textField's background separately?

    • PPL
      PPL about 6 years
    • JsW
      JsW about 6 years
      @PPL That's actually the same with mine demo code. It's working for UISearchBar but not in UISearchController set to navigationItem.seachController.
  • JsW
    JsW about 6 years
    Have you tried it in UISearchController? It's nor working in my code.
  • JsW
    JsW about 6 years
    Thanks, your code helped me. Please check the update. It still has other problem.
  • JsW
    JsW about 6 years
    Thanks, set them in viewDidAppear did help. But it still have other problem. Please check the update.
  • R. K.
    R. K. about 6 years
    Updated the answer to customize all the colors in UISearchController.
  • JAHelia
    JAHelia about 5 years
    cancel button text color didn't change using your updated solution
  • Mohamed Fadl Allah
    Mohamed Fadl Allah about 3 years
    @Kurnal is that a private API hacking or its safe to change textfield in that way ?