Change the color of UISearchBar text in iOS 7

How to change text color of UISearchBar in iOS 7 ?

In iOS 6 I subclassed UISearchBar and layoutSubviews by setting the UITextField subview UISearchBar properties.

But in iOS 7 , UISearchBar does not have a UITextField as a subquery. How to fix it?

+50
ios7 uisearchbar
Sep 27 '13 at 10:41
source share
16 answers

In iOS 7, you need to confirm the level again to access the text field. Change your code as follows

 for (UIView *subView in self.searchBar.subviews) { for (UIView *secondLevelSubview in subView.subviews){ if ([secondLevelSubview isKindOfClass:[UITextField class]]) { UITextField *searchBarTextField = (UITextField *)secondLevelSubview; //set font color here searchBarTextField.textColor = [UIColor blackColor]; break; } } } 

Note. This is not an open API.

OR

You can use the UIControls, Like property appearance.

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}]; 

Note. Appearance proxy can be used for iOS 9.0+ Audio output

enter image description here

You can set tintcolor to apply to key elements in the search bar .

Use tintcolor to align foreground elements.

Use barTintColor to tint the background.

In iOS v7.0, all subclasses of UIView get their behavior for tintColor from the base class. See the tintColor talk at the UIView level for more information. Apple doc

+101
Sep 27 '13 at 10:46
source share

You can set the text color with

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor blueColor]]; 
+94
Oct 11 '13 at 10:28
source share

For Xcode 6 (iOS8 SDK) the following DOES NOT WORK

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

But the following works (for deployment in iOS7 and iOS8)

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}]; 
+34
Sep 30 '14 at 1:07
source share

Although it is true that the UIAppearance protocol is a "public API", it is not that it supports UITextField.

If you look at UITextField.h and find the string "UI_APPEARANCE_SELECTOR", you will see that it has no instances of this string. If you look at UIButton, you will find a lot - these are all properties that are officially supported by the UIAppearance API. It is somewhat well known that UITextField is not supported by the UIAppearance API, so the code in the Sandeep answer does not always work, and in fact this is not the best approach.

This is a useful post with useful links: http://forums.xamarin.com/discussion/175/uitextfield-appearance

The correct approach, unfortunately, is messy - iterating through subviews (or subviews of the main subview for iOS7) and installing it manually. Otherwise, you will have unreliable results. But you can simply create a category for the UISearchBar and add the color method setTextColor: (UIColor *). Example:

 - (void)setTextColor:(UIColor*)color { for (UIView *v in self.subviews) { if([Environment isVersion7OrHigher]) //checks UIDevice#systemVersion { for(id subview in v.subviews) { if ([subview isKindOfClass:[UITextField class]]) { ((UITextField *)subview).textColor = color; } } } else { if ([v isKindOfClass:[UITextField class]]) { ((UITextField *)v).textColor = color; } } } } 
+5
Nov 21 '13 at 17:10
source share

Caution: this should lead to application failure!

KVC FTW. It did it for me.

 UITextField *searchField = [self.searchBar valueForKey:@"_searchField"]; searchField.textColor = [UIColor redColor]; 
+5
May 12 '14 at 21:32
source share

You can set text attributes like this:

 [[UITextField appearanceWhenContainedIn:[<YOUR_CONTROLLER_NAME> class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName:[UIFont systemFontOfSize:14.0]}]; 
+4
04 Sep '14 at 12:40
source share

Here is an example of work done in C # using Xamarin:

 SearchBar = new UISearchBar (); foreach (var subView in SearchBar.Subviews) { foreach (var field in subView.Subviews) { if (field is UITextField) { UITextField textField = (UITextField)field; textField.TextColor = UIColor.White; } } } 

Hope this helps someone.

+4
Sep 04 '14 at 15:12
source share

This seems to be the correct answer .

Swift Version:

 UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).textColor = UIColor.blueColor() 

This will only work for iOS 9.0 , to make it work for lower versions, you will need to follow this question. stack overflow

+4
Jan 05 '16 at 17:01
source share

Quick expansion

 public extension UISearchBar { public func setTextColor(color: UIColor) { let svs = subviews.flatMap { $0.subviews } guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return } tf.textColor = color } } 
+4
Mar 15 '16 at 10:17
source share

In my case, I have several UISearchBar objects and they need to change the font color of textField . appearanceWhenContainedIn updates the behavior of the UISearchBar , but another does not work.

I will subclass UISearchBar and implement custom -(id)initWithFrame: like the following, and it works.

 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.searchBarStyle = UISearchBarStyleMinimal; self.tintColor = [UIColor whiteColor]; self.barTintColor = [UIColor whiteColor]; [[UITextField appearanceForTraitCollection:self.traitCollection whenContainedIn:[self class], nil] setDefaultTextAttributes: @{ NSForegroundColorAttributeName : [UIColor whiteColor] }]; } return self; } 

The UIAppearance protocol link reported that

In other words, the containment operator in the appearance of WhenContainedIn: is treated as a partial order. Given the specific ordering (the actual hierarchy of the subordination), UIKit selects the partial ordering, which is the first unique match when reading the actual hierarchy from the window down.

So appearanceWhenContainedIn: will not handle all the UISearchBar in the UIWindow hierarchy. And that suggests that.

Use the ForTraitCollection: appearance and the ForTraitCollection: whenContainedIn: appearance methods to extract proxies for a class with the specified collection of attributes.

+2
Apr 21 '15 at 9:10
source share

The easiest way to do this is to put this code in viewDidAppear or viewWillAppear :

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]; 

This works on iOS 8 and Xcode 6 , unlike other code. This can ruin the font and size of the text, etc., but you can change this in text attributes.

This changes the color of the text for all search strings in your application. If you want to change it, use the code above, and then in any other views using the search bar use the same code, but set the color as you wish.

+1
Dec 26 '14 at 3:25
source share

you can use the search bar inside the text box

  UISearchBar * searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 50, 320, 44) ]; searchBar.autocorrectionType = UITextAutocapitalizationTypeWords; searchBar.delegate = self; searchBar.searchBarStyle = UISearchBarStyleMinimal; searchBar.barTintColor = [UIColor redColor]; [[UITextField appearanceWhenContainedIn:[searchBar class], nil]setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]; [self.view addSubview:searchBar]; 
+1
Jul 22. '15 at 18:34
source share

Update in Swift 3

 UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black 
+1
Jun 12 '17 at 10:31 on
source share

Although I would prefer to use the appearance API, it did not work with iOS8. Here's the least hacky solution I've come across:

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (self.shouldEnableSearchBar) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^ { UITextField *searchBarTextField = [[AFPBaseViewController findSubviewsOfView:self.searchBar ofClass:[UITextField class]] firstObject]; searchBarTextField.textColor = AFPConstantsColorGold; }); } } 

Perhaps you can even create a UIView category. The reason this should be called in viewDidAppear is because the UISearchBar is actually contained in the ViewController and does not load all of its child objects until it appears on the screen. It can also be added to viewWillAppear, but I have not tested it.

 + (NSArray *)findSubviewsOfView:(UIView *)view ofClass:(Class)class { NSMutableArray *targetSubviews = [NSMutableArray new]; for (id subview in view.subviews) { if ([subview isKindOfClass:class]) { [targetSubviews addObject:subview]; } if ([subview subviews].count) { [targetSubviews addObjectsFromArray:[self findSubviewsOfView:subview ofClass:class]]; } } return targetSubviews.copy; } 
0
Sep 20 '14 at 8:11
source share

This is the right solution for iOS8:

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:14], NSForegroundColorAttributeName:[UIColor lightGrayColor]}]; 

You must also install the font, otherwise the font size will be incorrect.

0
Mar 29 '15 at 15:19
source share

This class will give you complete control over each item in the UISearchBar




 import UIKit class SMTSearchBar: UISearchBar { override init(frame: CGRect) { super.init(frame: frame) initialize() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! initialize() } convenience init() { self.init(frame: CGRectZero) initialize() } // Style the view func initialize() { // Search Area let searchField = valueForKey("searchField") as! UITextField searchField.textColor = Colors.White searchField.font = UIFont(name: Fonts.MuseoSans500, size: 16) searchField.backgroundColor = Colors.Black.colorWithAlphaComponent(0.1) // Icons let searchIcon = UIImage(named: Icons.Search)?.imageWithTint(Colors.White) let smallClearIconNormal = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White) let smallClearIconHighLight = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White.colorWithAlphaComponent(0.5)) setImage(searchIcon, forSearchBarIcon: .Search, state: .Normal) setImage(smallClearIconHighLight, forSearchBarIcon: .Clear, state: .Highlighted) setImage(smallClearIconNormal, forSearchBarIcon: .Clear, state: .Normal) } func setPlaceHolder(placeholder: String) { for subView in subviews{ for subsubView in subView.subviews { if let textField = subsubView as? UITextField { textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSForegroundColorAttributeName: Colors.White.colorWithAlphaComponent(0.5)]) } } } } } 

Usage (in the navigation bar)

 let searchBar:SMTSearchBar = SMTSearchBar() searchBar.sizeToFit() searchBar.setPlaceHolder("Search for cool things") navigationItem.titleView = searchBar searchBar.becomeFirstResponder() 
0
Jul 27 '16 at 16:05
source share



All Articles