How to change UISearchBar font color and hue color of an image?

I have been trying to find the search results for several hours, but I cannot figure it out. Perhaps this is not possible. I am trying to change the hue color of the placeholder text and magnifying glass of a UISearchBar. I mean only iOS 8.0+, if that matters. Here is my code and what it looks like now:

let searchBar = UISearchBar() searchBar.placeholder = "Search" searchBar.searchBarStyle = UISearchBarStyle.Minimal searchBar.tintColor = UIColor.whiteColor() 

a busy cat

I would like the search and the magnifying glass to be white or, possibly, dark green.

+24
ios iphone uikit xcode swift
Mar 31 '15 at 18:20
source share
11 answers

If you have a custom image that you can use, you can set the image and change the color of the placeholder text using something similar to the following:

 [searchBar setImage:[UIImage imageNamed:@"SearchWhite"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; UITextField *searchTextField = [searchBar valueForKey:@"_searchField"]; if ([searchTextField respondsToSelector:@selector(setAttributedPlaceholder:)]) { UIColor *color = [UIColor purpleColor]; [searchTextField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"Search" attributes:@{NSForegroundColorAttributeName: color}]]; } 

In this example, I used purpleColor, instead you can use the + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha to create your custom dark green color .

EDIT: I just realized that you are writing this fast ... duh. Quickly typed this, so I did not leave the answer in Obj-C only.

  searchBar.setImage(UIImage(named: "SearchWhite"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal); var searchTextField: UITextField? = searchBar.valueForKey("searchField") as? UITextField if searchTextField!.respondsToSelector(Selector("attributedPlaceholder")) { var color = UIColor.purpleColor() let attributeDict = [NSForegroundColorAttributeName: UIColor.purpleColor()] searchTextField!.attributedPlaceholder = NSAttributedString(string: "search", attributes: attributeDict) } 

Swift 3.0

  var searchTextField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField if searchTextField!.responds(to: #selector(getter: UITextField.attributedPlaceholder)) { let attributeDict = [NSForegroundColorAttributeName: UIColor.white] searchTextField!.attributedPlaceholder = NSAttributedString(string: "Search", attributes: attributeDict) } 
+30
Mar 31 '15 at 18:51
source share

More details

  • Xcode Version 11.0 (11A420a), iOS 13, swift 5

Decision

 import UIKit extension UISearchBar { func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField } func set(textColor: UIColor) { if let textField = getTextField() { textField.textColor = textColor } } func setPlaceholder(textColor: UIColor) { getTextField()?.setPlaceholder(textColor: textColor) } func setClearButton(color: UIColor) { getTextField()?.setClearButton(color: color) } 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 } } func setSearchImage(color: UIColor) { guard let imageView = getTextField()?.leftView as? UIImageView else { return } imageView.tintColor = color imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate) } } private extension UITextField { private class Label: UILabel { private var _textColor = UIColor.lightGray override var textColor: UIColor! { set { super.textColor = _textColor } get { return _textColor } } init(label: UILabel, textColor: UIColor = .lightGray) { _textColor = textColor super.init(frame: label.frame) self.text = label.text self.font = label.font } required init?(coder: NSCoder) { super.init(coder: coder) } } private class ClearButtonImage { static private var _image: UIImage? static private var semaphore = DispatchSemaphore(value: 1) static func getImage(closure: @escaping (UIImage?)->()) { DispatchQueue.global(qos: .userInteractive).async { semaphore.wait() DispatchQueue.main.async { if let image = _image { closure(image); semaphore.signal(); return } guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return } let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44)) window.rootViewController?.view.addSubview(searchBar) searchBar.text = "txt" searchBar.layoutIfNeeded() _image = searchBar.getTextField()?.getClearButton()?.image(for: .normal) closure(_image) searchBar.removeFromSuperview() semaphore.signal() } } } } func setClearButton(color: UIColor) { ClearButtonImage.getImage { [weak self] image in guard let image = image, let button = self?.getClearButton() else { return } button.imageView?.tintColor = color button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal) } } var placeholderLabel: UILabel? { return value(forKey: "placeholderLabel") as? UILabel } func setPlaceholder(textColor: UIColor) { guard let placeholderLabel = placeholderLabel else { return } let label = Label(label: placeholderLabel, textColor: textColor) setValue(label, forKey: "placeholderLabel") } func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton } } 

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 = .default view.addSubview(searchBar) searchBar.placeholder = "placeholder" searchBar.set(textColor: .brown) searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3)) searchBar.setPlaceholder(textColor: .white) searchBar.setSearchImage(color: .white) searchBar.setClearButton(color: .red) } } 

Result

enter image description here enter image description here

+80
Jan 19 '17 at 15:00
source share

Swift 3: If you want to change the placeholder, glass and magnifier glass

  let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField textFieldInsideSearchBar?.textColor = UIColor.white let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel textFieldInsideSearchBarLabel?.textColor = UIColor.white let clearButton = textFieldInsideSearchBar?.value(forKey: "clearButton") as! UIButton clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal) clearButton.tintColor = UIColor.white let glassIconView = textFieldInsideSearchBar?.leftView as? UIImageView glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate) glassIconView?.tintColor = UIColor.white 
+9
Nov 20 '16 at 16:11
source share

You can change the color of the text without violating the private api rule:

 UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.whiteColor() 
+4
Mar 01 '16 at 7:48
source share

I found a way to change textfiled in the search bar. It works in fast 3 and Xcode8.

First, a subclass of the UISearchBar class.

 class CustomSearchBar: UISearchBar { 

UISearchBar includes a view that has the important text field that you want. The following function gets the index in subviews.

 func indexOfSearchFieldInSubviews() -> Int! { var index: Int! let searchBarView = subviews[0] for (i, subview) in searchBarView.subviews.enumerated() { if subview.isKind(of: UITextField.self) { index = i break } } return index } override func draw(_ rect: CGRect) { // Find the index of the search field in the search bar subviews. if let index = indexOfSearchFieldInSubviews() { // Access the search field let searchField: UITextField = subviews[0].subviews[index] as! UITextField // Set its frame. searchField.frame = CGRect(x: 5, y: 5, width: frame.size.width - 10, height: frame.size.height - 10) // Set the font and text color of the search field. searchField.font = preferredFont searchField.textColor = preferredTextColor // Set the placeholder and its color let attributesDictionary = [NSForegroundColorAttributeName: preferredPlaceholderColor.cgColor] searchField.attributedPlaceholder = NSAttributedString(string: preferredPlaceholder, attributes: attributesDictionary) // Set the background color of the search field. searchField.backgroundColor = barTintColor } super.draw(rect) } 

There you go, enjoy it.

+1
Oct 18 '16 at 9:58
source share

I could not get it to work with any of the above solutions.

I created the following UISearchBar category that works correctly on iOS 8.4 and 10.3 :

UISearchBar + PlaceholderColor.h

 #import <UIKit/UIKit.h> @interface UISearchBar (PlaceholderColor) - (void)setPlaceholderColor:(UIColor *)placeholderColor; @end 

UISearchBar + PlaceholderColor.m

 #import "UISearchBar+PlaceholderColor.h" @implementation UISearchBar (PlaceholderColor) - (void)setPlaceholderColor:(UIColor *)placeholderColor { UILabel *labelView = [self searchBarTextFieldLabelFromView:self]; [labelView setTextColor:placeholderColor]; } - (UILabel *)searchBarTextFieldLabelFromView:(UIView *)view { for (UIView *v in [view subviews]) { if ([v isKindOfClass:[UILabel class]]) { return (UILabel *)v; } UIView *labelView = [self searchBarTextFieldLabelFromView:v]; if (labelView) { return (UILabel *)labelView; } } return nil; } @end 

USING

 [mySearchBar setPlaceholderColor:[UIColor redColor]]; 

IMPORTANT NOTE:

Make sure you call setPlaceholderColor: AFTER your UISearchBar is added to the view and creates its own view hierarchy.

If you open the search panel programmatically, name it AFTER your call to startFirstResponder, as such:

 [mySearchBar becomeFirstResponder]; [searchBar setPlaceholderColor:[UIColor redColor]]; 

Otherwise, if you use UISearchBarDelegate :

 - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { [searchBar setPlaceholderColor:[UIColor redColor]]; } 
+1
Jun 02 '17 at 12:39 on
source share

A small update for Vasily Bodnarchuk is a great answer.

Swift 4+

NSForegroundColorAttributeName been changed to NSAttributedStringKey.foregroundColor

+1
Aug 07 '17 at 18:43 on
source share

I made a Swift 4.1 search bar extension:

 import Foundation import UIKit extension UISearchBar{ func setTextField(placeHolderColor:UIColor = .gray,placeHolder:String = "Search Something",textColor:UIColor = .white,backgroundColor:UIColor = .black, placeHolderFont:UIFont = UIFont.systemFont(ofSize: 12.0), textFont:UIFont = UIFont.systemFont(ofSize: 12.0) ){ for item in self.subviews{ for mainView in (item as UIView).subviews{ mainView.backgroundColor = backgroundColor if mainView is UITextField{ let textField = mainView as? UITextField if let _textF = textField{ _textF.text = "success" _textF.textColor = textColor _textF.font = textFont _textF.attributedPlaceholder = NSMutableAttributedString.init(string: placeHolder, attributes: [NSAttributedStringKey.foregroundColor : placeHolderColor, NSAttributedStringKey.font : placeHolderFont]) } } } } } } 

You can use this for your searchBar as follows:

 controller.searchBar.setTextField(placeHolderColor: .white, placeHolder: "Search A Pet", textColor: .white, backgroundColor: .green, placeHolderFont: UIFont.systemFont(ofSize: 14.0), textFont: UIFont.systemFont(ofSize: 14.0)) 
+1
Jul 26 '18 at 4:06
source share
 extension UISearchBar { var textField: UITextField? { return value(forKey: "searchField") as? UITextField } var placeholderLabel: UILabel? { return textField?.value(forKey: "placeholderLabel") as? UILabel } var icon: UIImageView? { return textField?.leftView as? UIImageView } var iconColor: UIColor? { get { return icon?.tintColor } set { icon?.image = icon?.image?.withRenderingMode(.alwaysTemplate) icon?.tintColor = newValue } } } 
+1
Aug 08 '18 at 17:01
source share

For anyone who just tries to change the text and does not see the updated placeholder, it worked for me, putting it here instead of viewDidLoad .

 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.searchBar.placeholder = @"My Custom Text"; } 
0
Jan 30 '18 at 22:15
source share

Swift 4 assumes that your search controller is configured as follows:

 let searchController = UISearchController(searchResultsController: nil) 

then set the text placeholder as follows:

 searchController.searchBar.placeholder = "Here is my custom text" 
-3
Feb 28 '18 at 0:25
source share



All Articles