Reputation: 8138
I know how to remove/change UISearchBar
background color around search field:
[[self.searchBar.subviews objectAtIndex:0] removeFromSuperview];
self.searchBar.backgroundColor = [UIColor grayColor];
But don't know how to do this inside it like that:
This needs to be compatible with iOS 4.3+.
Upvotes: 68
Views: 77080
Reputation: 181
try this in iOS13 in swift
@IBOutlet weak var searchBar: UISearchBar!
searchBar.barTintColor = .systemIndigo
searchBar.searchTextField.backgroundColor = .white
Upvotes: 6
Reputation: 41
Use it to update search textfield backgroud_color for xcode10 and xcode11 working fine for me
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor greenColor]];
Upvotes: 1
Reputation: 318
Searchbar now has a new instance property SearchTextField starting iOS 13, https://developer.apple.com/documentation/uikit/uisearchbar/3175433-searchtextfield
if(@available(iOS 13, *))
searchBar.searchTextField.backgroundColor = [UIColor whiteColor];
searchBar.searchTextField.textColor = [UIColor blackColor];
else{
//API that supports below iOS 13
//This will set it for all the UISearchBars in your application
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setBackgroundColor:[UIColor whiteColor]];
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blackColor]];
}
Upvotes: 3
Reputation: 657
iOS 13, Swift 5
searchBar.searchTextField.backgroundColor = .gray
searchBar.searchTextField.tintColor = .white
searchBar.searchTextField.textColor = .white
Upvotes: 2
Reputation: 25294
UISearchBar customising sample
import UIKit
extension UISearchBar {
func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
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
}
}
}
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))
//searchBar.searchBarStyle = .prominent
view.addSubview(searchBar)
searchBar.placeholder = "placeholder"
searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
searchBar.searchBarStyle = .prominent // or default
searchBar.searchBarStyle = .minimal
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 = .minimal
searchBar.searchBarStyle = .prominent
view.addSubview(searchBar)
searchBar.placeholder = "placeholder"
searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
}
}
Upvotes: 42
Reputation: 434
To do this on iOS 13+,
searchController.searchBar.searchTextField.backgroundColor = // your color here
Do note that by default the searchTextField.borderStyle
is set to roundedRect
, which applies a slight gray overlay on top of the color that you will set. If this is undesired, do
searchController.searchBar.searchTextField.borderStyle = .none
This will get rid of the gray overlay, but also get rid of the rounded corners.
Upvotes: 14
Reputation: 101
This helped me to change the background color of textField in searchbar.
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .white
Upvotes: -1
Reputation: 1271
With Swift 4, I would recommend that you only do this, no additional code needed:
self.searchBar.searchBarStyle = .prominent
self.searchBar.barStyle = .black
You can also change .prominent to .minimal should you not want the outer background to be grey.
Upvotes: 1
Reputation: 5420
This Worked for me.
- (void)setupSearchBar
{
[self.searchBar setReturnKeyType:UIReturnKeySearch];
[self.searchBar setEnablesReturnKeyAutomatically:NO];
[self.searchBar setPlaceholder:FOLocalizedString(@"search", nil)];
[self.searchBar setBackgroundImage:[UIImage new]];
[self.searchBar setBackgroundColor:[UIColor myGreyBGColor]];
[self.searchBar setBarTintColor:[UIColor myGreyBGColor]];
[self.searchBar setTintColor:[UIColor blueColor]];
}
Upvotes: 0
Reputation: 436
@EvGeniy Ilyin EvGeniy Ilyin's solution is the best. I wrote an Objective-C version based on this solution.
Create a UIImage
category, and advertise two class methods in UIImage+YourCategory.h
+ (UIImage *)imageWithColor:(UIColor *)color withSize:(CGRect)imageRect;
+ (UIImage *)roundImage:(UIImage *)image withRadius:(CGFloat)radius;
Implement methods in UIImage+YourCategory.m
// create image with your color
+ (UIImage *)imageWithColor:(UIColor *)color withSize:(CGRect)imageRect
{
UIGraphicsBeginImageContext(imageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, imageRect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
// get a rounded-corner image from UIImage instance with your radius
+ (UIImage *)roundImage:(UIImage *)image withRadius:(CGFloat)radius
{
CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
rect.size = image.size;
UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect
cornerRadius:radius];
[path addClip];
[image drawInRect:rect];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Make your own UISearchBar
in your ViewController
CGRect rect = CGRectMake(0.0, 0.0, 44.0, 30.0);
UIImage *colorImage = [UIImage imageWithColor:[UIColor yourColor] withSize:rect];
UIImage *finalImage = [UIImage roundImage:colorImage withRadius:4.0];
[yourSearchBar setSearchFieldBackgroundImage:finalImage forState:UIControlStateNormal];
Upvotes: 0
Reputation: 576
For Swift 3+, use this:
for subView in searchController.searchBar.subviews {
for subViewOne in subView.subviews {
if let textField = subViewOne as? UITextField {
subViewOne.backgroundColor = UIColor.red
//use the code below if you want to change the color of placeholder
let textFieldInsideUISearchBarLabel = textField.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideUISearchBarLabel?.textColor = UIColor.blue
}
}
}
Upvotes: 1
Reputation: 1929
what about apple way?
UISearchBar.appearance().setSearchFieldBackgroundImage(myImage, for: .normal)
But if you want create all programmaticle, you ca do this
my solution on Swift 3
let searchFieldBackgroundImage = UIImage(color: .searchBarBackground, size: CGSize(width: 44, height: 30))?.withRoundCorners(4)
UISearchBar.appearance().setSearchFieldBackgroundImage(searchFieldBackgroundImage, for: .normal)
where i use helpers extension
public extension UIImage {
public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else { return nil }
self.init(cgImage: cgImage)
}
public func withRoundCorners(_ cornerRadius: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let rect = CGRect(origin: CGPoint.zero, size: size)
let context = UIGraphicsGetCurrentContext()
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
context?.beginPath()
context?.addPath(path.cgPath)
context?.closePath()
context?.clip()
draw(at: CGPoint.zero)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return image;
}
}
Upvotes: 17
Reputation: 3549
Swift 3
for subview in searchBar.subviews {
for innerSubview in subview.subviews {
if innerSubview is UITextField {
innerSubview.backgroundColor = UIColor.YOUR_COLOR_HERE
}
}
}
Upvotes: 1
Reputation: 20541
Use this code to change the searchBar's UITextField
backgroundImage:
UITextField *searchField;
NSUInteger numViews = [searchBar.subviews count];
for (int i = 0; i < numViews; i++) {
if ([[searchBar.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) { //conform?
searchField = [searchBar.subviews objectAtIndex:i];
}
}
if (searchField) {
searchField.textColor = [UIColor whiteColor];
[searchField setBackground: [UIImage imageNamed:@"yourImage"]]; //set your gray background image here
[searchField setBorderStyle:UITextBorderStyleNone];
}
Use the below code to change the UISearchBarIcon
:
UIImageView *searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourSearchBarIconImage"]];
searchIcon.frame = CGRectMake(10, 10, 24, 24);
[searchBar addSubview:searchIcon];
[searchIcon release];
Also, to change the searchBar icon you can use the following built-in method on UISearchBar
(which is available from iOS 5+):
- (void)setImage:(UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state
Here you can set 4 types of UISearchBarIcon
i.e.:
UISearchBarIconBookmark
UISearchBarIconClear
UISearchBarIconResultsList
UISearchBarIconSearch
I hope this help you...
Upvotes: 36
Reputation: 1651
I've found this to be the best way to customize the appearance of various search bar attributes in Swift 2.2 and iOS 8+ using UISearchBarStyle.Minimal
searchBar = UISearchBar(frame: CGRectZero)
searchBar.tintColor = UIColor.whiteColor() // color of bar button items
searchBar.barTintColor = UIColor.fadedBlueColor() // color of text field background
searchBar.backgroundColor = UIColor.clearColor() // color of box surrounding text field
searchBar.searchBarStyle = UISearchBarStyle.Minimal
// Edit search field properties
if let searchField = searchBar.valueForKey("_searchField") as? UITextField {
if searchField.respondsToSelector(Selector("setAttributedPlaceholder:")) {
let placeholder = "Search"
let attributedString = NSMutableAttributedString(string: placeholder)
let range = NSRange(location: 0, length: placeholder.characters.count)
let color = UIColor(white: 1.0, alpha: 0.7)
attributedString.addAttribute(NSForegroundColorAttributeName, value: color, range: range)
attributedString.addAttribute(NSFontAttributeName, value: UIFont(name: "AvenirNext-Medium", size: 15)!, range: range)
searchField.attributedPlaceholder = attributedString
searchField.clearButtonMode = UITextFieldViewMode.WhileEditing
searchField.textColor = .whiteColor()
}
}
// Set Search Icon
let searchIcon = UIImage(named: "search-bar-icon")
searchBar.setImage(searchIcon, forSearchBarIcon: .Search, state: .Normal)
// Set Clear Icon
let clearIcon = UIImage(named: "clear-icon")
searchBar.setImage(clearIcon, forSearchBarIcon: .Clear, state: .Normal)
// Add to nav bar
searchBar.sizeToFit()
navigationItem.titleView = searchBar
Upvotes: 7
Reputation: 7434
This is the Swift version ( swift 2.1 /IOS 9 )
for view in searchBar.subviews {
for subview in view.subviews {
if subview .isKindOfClass(UITextField) {
let textField: UITextField = subview as! UITextField
textField.backgroundColor = UIColor.lightGrayColor()
}
}
}
Upvotes: 3
Reputation: 9337
Solution which doesn't involve any private API ! :)
Currently (probably since iOS 5 ) you can do this, for simply one colour cases, in this way:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor redColor]];
but please keep in mind that as it basis on appearance the change will be global for the app (it can be an advantage or a disadvantage of the solution).
For Swift you can use (it will work for iOS 9 and above):
if #available(iOS 9.0, *) {
UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.darkGrayColor()
}
You do not need #available
if your project supports iOS 9 and newer.
If you need to support earlier versions of iOS and want to use Swift take a look at this question.
Upvotes: 39
Reputation: 756
For iOS 9 use this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Remove lag on oppening the keyboard for the first time
UITextField *lagFreeField = [[UITextField alloc] init];
[self.window addSubview:lagFreeField];
[lagFreeField becomeFirstResponder];
[lagFreeField resignFirstResponder];
[lagFreeField removeFromSuperview];
//searchBar background color change
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setBackgroundColor:[UIColor greenColor]];
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blackColor];
return YES;
}
Upvotes: 1
Reputation: 8880
As Accatyyc says for iOS5+ use setSearchFieldBackgroundImage, but you either need to create a graphic, or do the following:
CGSize size = CGSizeMake(30, 30);
// create context with transparent background
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0,30,30)
cornerRadius:5.0] addClip];
[[UIColor grayColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.searchBar setSearchFieldBackgroundImage:image forState:UIControlStateNormal];
Upvotes: 20
Reputation: 5852
A better solution is to set the appearance of the UITextField
inside UISearchBar
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor grayColor]];
Upvotes: 5
Reputation: 212
- (void)viewDidLoad
{
[super viewDidLoad];
[[self searchSubviewsForTextFieldIn:self.searchBar] setBackgroundColor:[UIColor redColor]];
}
- (UITextField*)searchSubviewsForTextFieldIn:(UIView*)view
{
if ([view isKindOfClass:[UITextField class]]) {
return (UITextField*)view;
}
UITextField *searchedTextField;
for (UIView *subview in view.subviews) {
searchedTextField = [self searchSubviewsForTextFieldIn:subview];
if (searchedTextField) {
break;
}
}
return searchedTextField;
}
Upvotes: 3
Reputation: 46703
Just traverse all views using a category method (verified in iOS 7 and doesn't use private API):
@implementation UISearchBar (MyAdditions)
- (void)changeDefaultBackgroundColor:(UIColor *)color {
for (UIView *subview in self.subviews) {
for (UIView *subSubview in subview.subviews) {
if ([subSubview isKindOfClass:[UITextField class]]) {
UITextField *searchField = (UITextField *)subSubview;
searchField.backgroundColor = color;
break;
}
}
}
}
@end
So after importing the category into your class, just use it like:
[self.searchBar changeDefaultBackgroundColor:[UIColor grayColor]];
Keep in mind, if you put this immediately after the [[UISearchBar alloc] init]
line, it won't work yet since the subviews of the search bar are still being created. Put it a few lines down after you setup the rest of the search bar.
Upvotes: 4
Reputation: 4980
without using private API's:
for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) {
if ([subview isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField*)subview;
[textField setBackgroundColor:[UIColor redColor]];
}
}
Upvotes: 6
Reputation: 1234
Just customize the text field itself.
I am simply doing this and it works fine for me (iOS 7).
UITextField *txfSearchField = [_searchBar valueForKey:@"_searchField"];
txfSearchField.backgroundColor = [UIColor redColor];
This way you don't need to create an image, size it, etc...
Upvotes: 47
Reputation: 2294
For Changing Only Color :
searchBar.tintColor = [UIColor redColor];
For Applying Background Image :
[self.searchBar setSearchFieldBackgroundImage:
[UIImage imageNamed:@"Searchbox.png"]
forState:UIControlStateNormal];
Upvotes: 5
Reputation: 5828
According to the UISearchBar documentation:
You should use this function for iOS 5.0+.
- (void)setSearchFieldBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state
Usage example:
[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];
Sadly, in iOS 4 you need to revert to less sophisticated methods. See other answers.
Upvotes: 24