Cannot change search bar background color Cannot change search bar background color ios ios

Cannot change search bar background color


Like @aliamcami, all the answers before did not work as I would expect, either the answer did not work for me or it works but it needs too much "dummy" code. So I share another answer wrote in Swift 4 with simplified logic:

for textField in searchController.searchBar.subviews.first!.subviews where textField is UITextField {    textField.subviews.first?.backgroundColor = .white    textField.subviews.first?.layer.cornerRadius = 10.5 //I set 10.5 because is approximately the system value    textField.subviews.first?.layer.masksToBounds = true    //Continue changing more properties...}

textField.subviews.first is the "_UISearchBarSearchFieldBackgroundView" subview which add visual effects behind the UIFieldEditor.


Edited

After some development and many bugs, I finished with this elegant solution (that I am sure Apple would not be happy to approve, but I do not know) that works from iOS 10 to iOS 12:

if let textField = searchBar.value(forKey: "searchField") as? UITextField {    textField.backgroundColor = myColor    //textField.font = myFont    //textField.textColor = myTextColor    //textField.tintColor = myTintColor    // And so on...        let backgroundView = textField.subviews.first    if #available(iOS 11.0, *) { // If `searchController` is in `navigationItem`        backgroundView?.backgroundColor = UIColor.white.withAlphaComponent(0.3) //Or any transparent color that matches with the `navigationBar color`        backgroundView?.subviews.forEach({ $0.removeFromSuperview() }) // Fixes an UI bug when searchBar appears or hides when scrolling    }    backgroundView?.layer.cornerRadius = 10.5    backgroundView?.layer.masksToBounds = true    //Continue changing more properties...}

When the searchBar is in the tableHeaderView the above code can be called in viewWillAppear, but if it is in the navigationItem on iOS 11 and above it should be called in viewDidAppear.


If you only want to change it in your ViewController and don't want anywhere else to effect then use

for view in searchBar.subviews {            for subview in view.subviews {                if subview .isKindOfClass(UITextField) {                    let textField: UITextField = subview as! UITextField                    textField.backgroundColor = UIColor.redColor()                }            }        }

But if you want it to be change in whole app and targeting the iOS 9.0 or later then should be using appearanceWhenContainedInInstancesOfClasses like

UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.redColor()


I did one UISearchBar extension & category for customize text filed within search bar.

Compatible from iOS 9 to iOS 13.

Swift 4+

import UIKitextension UISearchBar {    // Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility    var compatibleSearchTextField: UITextField {        guard #available(iOS 13.0, *) else { return legacySearchField }        return self.searchTextField    }    private var legacySearchField: UITextField {        if let textField = self.subviews.first?.subviews.last as? UITextField {            // Xcode 11 previous environment            return textField        } else if let textField = self.value(forKey: "searchField") as? UITextField {            // Xcode 11 run in iOS 13 previous devices            return textField        } else {            // exception condition or error handler in here            return UITextField()        }    }}

Usage Example:

var searchController: UISearchController?searchController?.searchBar.compatibleSearchTextField.textColor = UIColor.XXXsearchController?.searchBar.compatibleSearchTextField.backgroundColor = UIColor.XXX

Objective-C

UISearchBar+SearchTextField.h

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface UISearchBar (SearchTextField)// Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility@property (nonatomic, readonly) UITextField *compatibleSearchTextField;@endNS_ASSUME_NONNULL_END

UISearchBar+SearchTextField.m

#import "UISearchBar+SearchTextField.h"@implementation UISearchBar (SearchTextField)- (UITextField *)compatibleSearchTextField {    if (@available(iOS 13.0, *)) {#ifdef __IPHONE_13_0        return self.searchTextField;#else        // Xcode 11 run in iOS 13 previous devices        return (UITextField *)[self valueForKey:@"searchField"];#endif    } else {        // Xcode 11 previous environment        return [[[self.subviews firstObject] subviews] lastObject];    }}@end

Usage Example:

- (UISearchBar *)searchBar {    if (!_searchBar) {        _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(X, X, X, X)];        _searchBar.compatibleSearchTextField.textColor = [UIColor XXX];        _searchBar.compatibleSearchTextField.backgroundColor = [UIColor XXX];    }    return _searchBar}