How to change background color of the text field in the UISearchController?
Solution 1
Here is a an example on how to set the textField
background.
class ViewController: UIViewController {
let searchController = UISearchController(searchResultsController: nil)
private lazy var searchTextField: UITextField? = { [unowned self] in
var textField: UITextField?
self.searchController.searchBar.subviews.forEach({ view in
view.subviews.forEach({ view in
if let view = view as? UITextField {
textField = view
}
})
})
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Candies"
navigationItem.searchController = searchController
definesPresentationContext = true
if let bg = self.searchTextField?.subviews.first {
bg.backgroundColor = .green
bg.layer.cornerRadius = 10
bg.clipsToBounds = true
}
}
}
Result
Solution 2
To update background of UISearchController proper way is change background image.
If you see UISearchController in visual debugger you can find out that background of it is UIImageView:
So you should make small image of your search bar and set it to seachBar like this:
lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.placeholder = "Search"
searchController.searchBar.tintColor = UIColor.black
searchController.searchBar.searchBarStyle = .minimal
// Set background image to searchBar so it will resize
searchController.searchBar.setSearchFieldBackgroundImage(UIImage(named: "oval_static"), for: .normal)
definesPresentationContext = true
return searchController
}()
The image of searchBar (in project I recommend use .pdf or .png format of image here just screenshot):
The UISearchBar will resize it as need it and result is:
Moreover we can do something like this to create custom background just in code:
/// Just random extension to make image from UIView, you can use your own
extension UIView {
func asImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
}}
lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.placeholder = "Search"
searchController.searchBar.tintColor = UIColor.black
searchController.searchBar.searchBarStyle = .minimal
// Create own view with custom properties
// Default height is 36 points
let differentColorSearchBar = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 36))
differentColorSearchBar.layer.cornerRadius = 8
differentColorSearchBar.clipsToBounds = true
differentColorSearchBar.backgroundColor = UIColor.blue
searchController.searchBar.setSearchFieldBackgroundImage(differentColorSearchBar.asImage(), for: .normal)
definesPresentationContext = true
return searchController
}
The Result is (of course you can change another properties of searchBar to make it better, but I just show you how change background properly):
I recommend avoid private properties just use open! Hope it's help.
Solution 3
On iOS13 and later, searchTextField is a member of UISearchBar. So you can use something like this:
searchController.searchBar.searchTextField.backgroundColor = UIColor.blue
Be careful, apple does not have proper notation in SDK showing that this property introduced in iOS 13, so if you are supporting iOS 12 or older it does not show you any warning. Make sure to wrap it for iOS 13 only.
Solution 4
I do it in this way, Objective-C code:
UITextField *searchField = [_navigationSearchBar valueForKey:@"searchField"];
searchField.backgroundColor = [UIColor defaultSeacrhBarColor];
searchField.textColor = [UIColor defaultWhiteColor];
searchField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:searchTitle];
UILabel *placeholderLabel = [searchField valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = [UIColor lightTextColor];
UIButton *clearButton = [searchField valueForKey:@"clearButton"];
[clearButton setImage:[clearButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
clearButton.tintColor = [UIColor defaultWhiteColor];
_navigationSearchBar.delegate = self;
[_navigationSearchBar setTranslucent:NO];
[_navigationSearchBar setBackgroundImage:nil];
[_navigationSearchBar setBarTintColor:[UIColor defaultNavigationBarColor]];
[_navigationSearchBar setBackgroundColor:[UIColor defaultNavigationBarColor]];
[_navigationSearchBar setImage:[UIImage imageNamed:@"Search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
_navigationSearchBar.clipsToBounds = YES;
[_navigationBar addSubview:_navigationSearchBar];
Solution 5
Max use this below function for changing color.
extension UISearchBar {
func setBackgroundColor(){
if let view:UIView = self.subviews.first {
for curr in view.subviews {
guard let searchBarBackgroundClass = NSClassFromString("UISearchBarBackground") else {
return
}
if curr.isKind(of:searchBarBackgroundClass){
if let imageView = curr as? UIImageView{
imageView.backgroundColor = .red
break
}
}
}
}
}
}
Use this function with searchbar.
searchBarController.searchBar.setBackgroundColor()
Comments
-
Max almost 2 years
How to change the default grey background at UISearchController search text field?
-
Francesco Destino over 5 yearsOkay! Maybe you can try with subviews inside of searchBar and if you find a subview that is a UITextField change its backgroundColor
-
Timur Bernikovich over 5 yearsNot the best way to find
UITextField
. Make it recursive at least. :( -
Kamran over 5 yearsWhen you write
.value(forKey: "searchField")
, you are calling Apple to reject your app anytime they notice. Also, your app is going to crash if they just rename thesearchField
attribute in any new version. -
Mayur Karmur over 5 years@Kamran, First of all, I have safely getting textField by optional unwrap by
if let
, So it will not crash app. Second thing, If app is live then how will it crash. Also, one of my app already live where this code is available. -
Kamran over 5 yearsYeah, optional unwrap will work if this
.value(forKey: "searchField")
doesn't crash. If it crashed inside this method, optional unwrap can not save you. If app is live and they renamed the attribute in new os then it will start crashing as this key will not be available. Lastly, your app and many other apps are live because Apple didn't notice that you are accessing aprivate
api. Anytime they notice this, they can reject the app.