web-dev-qa-db-fra.com

Comment changer la couleur de fond du composant UISearchBar sur iOS

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

achieved UISearchBar customization

Mais je ne sais pas comment faire ça à l'intérieur comme ça:

desired UISearchBar customization

Cela doit être compatible avec iOS 4.3+.

55
Borut Tomazin

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 .:

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

J'espère que cela vous aidera ...

33
Paras Joshi

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

48
AbuZubair

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.

35
Julian Król

Swift 3, xcode 8.2.1

Exemple de personnalisation de UISearchBar

Échantillon complet

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

Usage

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

Résultat 1

 searchBar.searchBarStyle = .prominent // or default

 enter image description here

Résultat 2

 searchBar.searchBarStyle = .minimal

 enter image description here

26
Vasily Bodnarchuk

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.

23
Accatyyc

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];
18
Nick H247

qu'en est-il de la manière Apple?

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

vous pouvez définir n'importe quelle image sur votre conception!

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

}
13
EvGeniy Ilyin

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

 enter image description here

7
Alex Koshy

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]];
    }
}
6
Tomer Even

Une meilleure solution consiste à définir l'apparence de UITextField à l'intérieur de UISearchBar

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

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.

5
iwasrobbed

Pour changer de couleur uniquement: 

searchBar.tintColor = [UIColor redColor];

Pour appliquer une image de fond:

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

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()
        }
    }
}
3

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;
}
1
Boris Nikolić

Swift 3

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

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

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]];
}
0
Varun Naharia

@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];
0
steveluoxin

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.

0
Apoorv Khatreja

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.

0
Chris Herbst