Cómo cambiar el color de fondo del componente UISearchBar en iOS

Sé cómo eliminar / cambiar el color de fondo de UISearchBar en el campo de búsqueda:

 [[self.searchBar.subviews objectAtIndex:0] removeFromSuperview]; self.searchBar.backgroundColor = [UIColor grayColor]; 

logró la personalización de UISearchBar

Pero no sé cómo hacer esto dentro de esa manera:

deseada personalización de UISearchBar

Esto debe ser compatible con iOS 4.3+.

Utilice este código para cambiar la imagen de fondo de UITextField la barra de UITextField :

 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 el siguiente código para cambiar UISearchBarIcon :

  UIImageView *searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourSearchBarIconImage"]]; searchIcon.frame = CGRectMake(10, 10, 24, 24); [searchBar addSubview:searchIcon]; [searchIcon release]; 

Además, para cambiar el ícono searchBar, puede usar el siguiente método UISearchBar en UISearchBar (que está disponible en iOS 5+ ):

 - (void)setImage:(UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state 

Aquí puede establecer 4 tipos de UISearchBarIcon es decir:

  1. UISearchBarIconBookmark
  2. UISearchBarIconClear
  3. UISearchBarIconResultsList
  4. UISearchBarIconSearch

Espero que esto te ayude...

Simplemente personalice el campo de texto en sí.

Simplemente estoy haciendo esto y funciona bien para mí (iOS 7).

 UITextField *txfSearchField = [_searchBar valueForKey:@"_searchField"]; txfSearchField.backgroundColor = [UIColor redColor]; 

De esta forma no es necesario crear una imagen, dimensionarla, etc.

¡Solución que no involucra ninguna API privada! 🙂

Actualmente ( probablemente desde iOS 5 ) puede hacer esto, para casos de un solo color, de esta manera:

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

pero tenga en cuenta que, como base de apariencia, el cambio será global para la aplicación (puede ser una ventaja o una desventaja de la solución).

Para Swift puedes usar (funcionará para iOS 9 y superior):

 if #available(iOS 9.0, *) { UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.darkGrayColor() } 

No necesita #available si su proyecto es compatible con iOS 9 y versiones posteriores.

Si necesita admitir versiones anteriores de iOS y desea usar Swift, eche un vistazo a esta pregunta.

Swift 3, xcode 8.2.1

UISearchBar muestra de personalización

Muestra completa

Extensión UISearchBar

 extension UISearchBar { private func getViewElement(type: T.Type) -> T? { let svs = subviews.flatMap { $0.subviews } guard let element = (svs.filter { $0 is T }).first as? T else { return nil } return element } func setTextFieldColor(color: UIColor) { if let textField = getViewElement(type: UITextField.self) { switch searchBarStyle { case .minimal: textField.layer.backgroundColor = color.cgColor textField.layer.cornerRadius = 6 case .prominent, .default: textField.backgroundColor = color } } } } 

Uso

 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.setTextFieldColor(color: UIColor.green.withAlphaComponent(0.3)) 

Resultado 1

  searchBar.searchBarStyle = .prominent // or default 

enter image description here

Resultado 2

  searchBar.searchBarStyle = .minimal 

enter image description here

De acuerdo con la documentación de UISearchBar :

Deberías usar esta función para iOS 5.0+.

 - (void)setSearchFieldBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state 

Ejemplo de uso:

 [mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal]; 

Lamentablemente, en iOS 4 necesita volver a métodos menos sofisticados. Ver otras respuestas

Como dice Accatyyc para iOS5 +, use setSearchFieldBackgroundImage, pero debe crear un gráfico o hacer lo siguiente:

 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]; 

¿Qué tal la forma de manzana?

 UISearchBar.appearance().setSearchFieldBackgroundImage(myImage, for: .normal) 

¡puedes configurar cualquier imagen en tu diseño!

Pero si quieres crear toda la programmaticle, puedes hacer esto


mi solución en Swift 3

 let searchFieldBackgroundImage = UIImage(color: .searchBarBackground, size: CGSize(width: 44, height: 30))?.withRoundCorners(4) UISearchBar.appearance().setSearchFieldBackgroundImage(searchFieldBackgroundImage, for: .normal) 

donde uso la extensión de ayudantes

 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; } } 

He encontrado que esta es la mejor manera de personalizar la apariencia de varios atributos de la barra de búsqueda en Swift 2.2 e iOS 8+ usando 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 

enter image description here

sin usar API privadas:

 for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) { if ([subview isKindOfClass:[UITextField class]]) { UITextField *textField = (UITextField*)subview; [textField setBackgroundColor:[UIColor redColor]]; } } 

Una mejor solución es establecer la apariencia del UITextField dentro de UISearchBar

 [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor grayColor]]; 

Simplemente recorra todas las vistas usando un método de categoría (verificado en iOS 7 y no usa API privada):

 @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 

Entonces, después de importar la categoría a tu clase, solo úsala como:

 [self.searchBar changeDefaultBackgroundColor:[UIColor grayColor]]; 

Tenga en cuenta que si coloca esto inmediatamente después de la línea [[UISearchBar alloc] init] , no funcionará todavía, ya que las subvistas de la barra de búsqueda aún se están creando. Colóquelo unas líneas después de configurar el rest de la barra de búsqueda.

Para cambiar solo color:

 searchBar.tintColor = [UIColor redColor]; 

Para aplicar la imagen de fondo:

 [self.searchBar setSearchFieldBackgroundImage: [UIImage imageNamed:@"Searchbox.png"] forState:UIControlStateNormal]; 
 - (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; } 

Esta es la versión Swift (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() } } } 

Para iOS 9 usa esto:

 - (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; } 

Swift 3

 for subview in searchBar.subviews { for innerSubview in subview.subviews { if innerSubview is UITextField { innerSubview.backgroundColor = UIColor.YOUR_COLOR_HERE } } } 

Para Swift 3+, usa esto:

 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 } } } 

La solución de @EvGeniy ​​Ilyin EvGeniy ​​Ilyin es la mejor. Escribí una versión de Objective-C basada en esta solución.

Crea una categoría de UIImage y anuncia dos métodos de clase en UIImage + YourCategory.h

 + (UIImage *)imageWithColor:(UIColor *)color withSize:(CGRect)imageRect; + (UIImage *)roundImage:(UIImage *)image withRadius:(CGFloat)radius; 

Implementar métodos en 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; } 

Crea tu propio UISearchBar en tu 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];