Jak zmienić kolor tła komponentu UISearchBar w systemie iOS

Wiem jak usunąć / zmienić UISearchBar kolor tła wokół pola wyszukiwania:

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

osiągnięta Personalizacja paska UISearchBar

Ale Nie wiem jak to zrobić w środku w ten sposób:

pożądane dostosowanie paska UISearchBar

To musi być zgodne z iOS 4.3+.
Author: Vadim Kotov, 2012-12-11

18 answers

Użyj tego kodu, aby zmienić pasek wyszukiwania 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];
}

Użyj poniższego kodu, aby zmienić UISearchBarIcon:

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

Ponadto, aby zmienić ikonę paska wyszukiwania, możesz użyć następującej wbudowanej metody na UISearchBar (która jest dostępna z iOS 5+):

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

Tutaj możesz ustawić 4 typy UISearchBarIcon tj.:

  1. UISearchBarIconBookmark
  2. UISearchBarIconClear
  3. UISearchBarIconResultsList
  4. UISearchBarIconSearch
Mam nadzieję, że to ci pomoże...
 33
Author: Paras Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 14:38:57

Po prostu dostosuj samo pole tekstowe.

Po prostu to robię i działa dobrze dla mnie (iOS 7).

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

W ten sposób nie trzeba tworzyć obrazu, rozmiar, itp...

 49
Author: AbuZubair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-10 00:01:29

Rozwiązanie, które nie obejmuje żadnego prywatnego API ! :)

Obecnie (prawdopodobnie od iOS 5 ) możesz to zrobić, dla jednego koloru, w ten sposób:

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

Należy jednak pamiętać, że ze względu na wygląd zmiana będzie globalna dla aplikacji (może to być zaleta lub wada rozwiązania).

Dla Swift możesz użyć (będzie działać na iOS 9 i nowszych):

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

Nie potrzebujesz #available Jeśli twój projekt obsługuje iOS 9 i nowsze.

Jeśli potrzebujesz wsparcia dla wcześniejszych wersji iOS i chcesz korzystać z Swift spójrz na to pytanie.

 35
Author: Julian Król,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:48

Swift 3, xcode 8.2.1

UISearchBar dostosowywanie próbki

Pełna próbka

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

Użycie

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

Wynik 1

 searchBar.searchBarStyle = .prominent // or default

Tutaj wpisz opis obrazka

Wynik 2

 searchBar.searchBarStyle = .minimal

Tutaj wpisz opis obrazka

 26
Author: Vasily Bodnarchuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:48

Zgodnie z UISearchBar documentation :

Powinieneś użyć tej funkcji dla iOS 5.0+.

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

Przykład użycia:

[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];
Niestety, w iOS 4 musisz wrócić do mniej wyrafinowanych metod. Zobacz inne odpowiedzi.
 23
Author: Accatyyc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-11 10:33:18

Jak mówi Accatyyc dla iOS5 + użyj setSearchFieldBackgroundImage, ale albo musisz utworzyć grafikę, albo wykonaj następujące czynności:

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
Author: Nick H247,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-06 14:35:52

A co z apple way?

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

Możesz ustawić dowolny obraz na swoim projekcie!

Ale jeśli chcesz utworzyć cały programmaticle, ca zrobić to


Moje rozwiązanie na Swift 3

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

Gdzie używam 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;
    }

}
 10
Author: EvGeniy Ilyin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-24 22:43:14

Uznałem, że jest to najlepszy sposób na dostosowanie wyglądu różnych atrybutów paska wyszukiwania w Swift 2.2 i iOS 8 + za pomocą 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

Tutaj wpisz opis obrazka

 7
Author: Alex Koshy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-16 18:31:55

Bez użycia prywatnych API:

for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) {
    if ([subview isKindOfClass:[UITextField class]]) {
        UITextField *textField = (UITextField*)subview;
        [textField setBackgroundColor:[UIColor redColor]];
    }
}
 6
Author: Tomer Even,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-07 12:39:41

Lepszym rozwiązaniem jest ustawienie wyglądu UITextField wewnątrz UISearchBar

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor grayColor]];
 6
Author: Mahmoud Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 13:17:42

Po prostu przejrzyj wszystkie widoki za pomocą metody kategorii (zweryfikowanej w iOS 7 i nie używającej prywatnego 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

Więc po zaimportowaniu kategorii do swojej klasy, użyj jej tak:

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

Pamiętaj, że jeśli umieścisz tę natychmiast po linii [[UISearchBar alloc] init], to nie będzie ona jeszcze działać, ponieważ podglądy paska wyszukiwania są nadal tworzone. Umieść go kilka linii w dół po skonfigurowaniu reszty paska wyszukiwania.

 5
Author: iwasrobbed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-06 04:06:36

Do Zmiany Tylko Koloru:

searchBar.tintColor = [UIColor redColor];

Do Zastosowania Obrazu Tła:

[self.searchBar setSearchFieldBackgroundImage:
                          [UIImage imageNamed:@"Searchbox.png"]
                                     forState:UIControlStateNormal];
 4
Author: Pushkraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 08:07:31
- (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
Author: Meerschwein Bob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-09 09:55:47

To jest wersja 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
Author: Chathuranga Silva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-07 16:13:47

Dla iOS 9 użyj tego:

- (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
Author: Boris Nikolić,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 01:27:44

Swift 3

for subview in searchBar.subviews {
    for innerSubview in subview.subviews {
        if innerSubview is UITextField {
            innerSubview.backgroundColor = UIColor.YOUR_COLOR_HERE
        }
    }
}
 1
Author: Chris Chute,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-15 17:57:58

Dla Swift 3+ Użyj tego:

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
Author: Alien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 08:54:22

@EvGeniy Ilyin rozwiązanie EvGeniy Ilyin jest najlepsze. Na podstawie tego rozwiązania napisałem wersję Objective-C.

Utwórz kategorię UIImage i Zareklamuj dwie metody klas w UIImage+YourCategory.h

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

Zaimplementuj metody w 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];
 0
Author: steveluoxin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-12 01:26:57