Je sais comment supprimer/modifier la couleur d'arrière-plan UISearchBar
autour du champ de recherche:
[[self.searchBar.subviews objectAtIndex:0] removeFromSuperview];
self.searchBar.backgroundColor = [UIColor grayColor];
Mais je ne sais pas comment faire ça à l'intérieur comme ça:
Cela doit être compatible avec iOS 4.3+.
Utilisez ce code pour modifier la UITextField
backgroundImage du searchBar:
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];
}
Utilisez le code ci-dessous pour changer la UISearchBarIcon
:
UIImageView *searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourSearchBarIconImage"]];
searchIcon.frame = CGRectMake(10, 10, 24, 24);
[searchBar addSubview:searchIcon];
[searchIcon release];
De plus, pour changer l'icône de la barre de recherche, vous pouvez utiliser la méthode intégrée suivante dans UISearchBar
(disponible à partir de iOS 5+ ):
- (void)setImage:(UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state
Ici, vous pouvez définir 4 types de UISearchBarIcon
i.e .:
UISearchBarIconBookmark
UISearchBarIconClear
UISearchBarIconResultsList
UISearchBarIconSearch
J'espère que cela vous aidera ...
Il suffit de personnaliser le champ de texte lui-même.
Je fais simplement ceci et cela fonctionne très bien pour moi (iOS 7).
UITextField *txfSearchField = [_searchBar valueForKey:@"_searchField"];
txfSearchField.backgroundColor = [UIColor redColor];
De cette façon, vous n'avez pas besoin de créer une image, de la redimensionner, etc ...
Solution qui n'implique aucune API privée! :)
Actuellement ( probablement depuis iOS 5 ), vous pouvez le faire, pour un seul cas de couleur, de cette façon:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor redColor]];
mais gardez à l'esprit que, comme il est basé sur l'apparence, le changement sera global pour l'application (cela peut être un avantage ou un inconvénient de la solution).
Pour Swift, vous pouvez utiliser (cela fonctionnera pour iOS 9 et supérieur):
if #available(iOS 9.0, *) {
UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.darkGrayColor()
}
Vous n'avez pas besoin de #available
si votre projet prend en charge iOS 9 et versions ultérieures.
Si vous devez prendre en charge des versions antérieures d’iOS et que vous souhaitez utiliser Swift, jetez un oeil à this question.
Swift 3, xcode 8.2.1
Exemple de personnalisation de UISearchBar
Extension UISearchBar
extension UISearchBar {
private func getViewElement<T>(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
}
}
}
}
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))
searchBar.searchBarStyle = .prominent // or default
searchBar.searchBarStyle = .minimal
Selon la documentation UISearchBar :
Vous devez utiliser cette fonction pour iOS 5.0+.
- (void)setSearchFieldBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state
Exemple d'utilisation:
[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];
Malheureusement, dans iOS 4, vous devez revenir à des méthodes moins sophistiquées. Voir d'autres réponses.
Comme Accatyyc le dit pour iOS5 +, utilisez setSearchFieldBackgroundImage, mais vous devez soit créer un graphique, soit procéder comme suit:
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'en est-il de la manière Apple?
UISearchBar.appearance().setSearchFieldBackgroundImage(myImage, for: .normal)
Mais si vous voulez créer tous les programmes, vous pouvez le faire.
ma solution sur Swift 3
let searchFieldBackgroundImage = UIImage(color: .searchBarBackground, size: CGSize(width: 44, height: 30))?.withRoundCorners(4)
UISearchBar.appearance().setSearchFieldBackgroundImage(searchFieldBackgroundImage, for: .normal)
où j'utilise l'extension helpers
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;
}
}
J'ai trouvé que c'était le meilleur moyen de personnaliser l'apparence des divers attributs de la barre de recherche dans Swift 2.2 et iOS 8+ à l'aide de 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
sans utiliser les API privées:
for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) {
if ([subview isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField*)subview;
[textField setBackgroundColor:[UIColor redColor]];
}
}
Une meilleure solution consiste à définir l'apparence de UITextField
à l'intérieur de UISearchBar
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor grayColor]];
Il suffit de parcourir toutes les vues à l'aide d'une méthode de catégorie (vérifiée dans iOS 7 et n'utilise pas d'API privée):
@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
Donc, après avoir importé la catégorie dans votre classe, utilisez-la comme suit:
[self.searchBar changeDefaultBackgroundColor:[UIColor grayColor]];
N'oubliez pas que si vous mettez immédiatement immédiatement après la ligne [[UISearchBar alloc] init]
, cela ne fonctionnera pas encore car les sous-vues de la barre de recherche sont toujours en cours de création. Placez-le quelques lignes après avoir configuré le reste de la barre de recherche.
Pour changer de couleur uniquement:
searchBar.tintColor = [UIColor redColor];
Pour appliquer une image de fond:
[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;
}
Ceci est la version 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()
}
}
}
Pour iOS 9, utilisez ceci:
- (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
}
}
}
Pour Swift 3+, utilisez ceci:
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
}
}
}
Cela a fonctionné pour moi.
- (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]];
}
@EvGeniy Ilyin EvGeniy La solution d'Ilyin est la meilleure ... J'ai écrit une version Objective-C basée sur cette solution.
Créez une catégorie UIImage
et publiez deux méthodes de classe dans UIImage + YourCategory.h
+ (UIImage *)imageWithColor:(UIColor *)color withSize:(CGRect)imageRect;
+ (UIImage *)roundImage:(UIImage *)image withRadius:(CGFloat)radius;
Implémenter des méthodes dans 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;
}
Créez votre propre UISearchBar
dans votre 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];
Pour ce faire sur iOS 13+,
searchController.searchBar.searchTextField.backgroundColor = // your color here
Notez que par défaut, searchTextField.borderStyle
est défini sur roundedRect
, ce qui applique une légère superposition de gris sur la couleur que vous définissez. Si cela n'est pas désiré, faites
searchController.searchBar.searchTextField.borderStyle = .none
Cela éliminera le calque gris, mais également les coins arrondis.
Avec Swift 4, je vous recommande de ne faire que cela, sans code supplémentaire:
self.searchBar.searchBarStyle = .prominent
self.searchBar.barStyle = .black
Vous pouvez également remplacer .prominent en .minimal si vous ne voulez pas que l’arrière-plan extérieur soit gris.