68

我知道如何删除/更改UISearchBar搜索字段周围的背景颜色:

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

实现 UISearchBar 自定义

但不知道如何在里面这样做:

所需的 UISearchBar 自定义

这需要与 iOS 4.3+ 兼容。

4

26 回答 26

47

只需自定义文本字段本身。

我只是这样做,它对我来说很好(iOS 7)。

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

这样您就不需要创建图像、调整大小等...

于 2013-10-10T00:01:29.540 回答
42

细节

  • Xcode 版本 11.0 (11A420a),快速 5

UISearchBar 自定义示例

解决方案

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

结果 1

 searchBar.searchBarStyle = .prominent // or default

在此处输入图像描述

结果 2

 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))
    }
}
于 2017-01-20T11:50:37.870 回答
39

不涉及任何私有 API 的解决方案!:)

目前(可能从 iOS 5 开始)您可以通过以下方式仅针对一种颜色情况执行此操作:

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

但请记住,由于它基于外观,更改将是应用程序的全局(它可能是解决方案的优点或缺点)。

对于 Swift,您可以使用(它适用于 iOS 9 及更高版本):

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

#available如果您的项目支持 iOS 9 及更高版本,则不需要。

如果您需要支持早期版本的 iOS 并想使用 Swift,请查看问题。

于 2014-08-12T08:58:49.327 回答
36

使用此代码更改 searchBar 的UITextFieldbackgroundImage:

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

使用以下代码更改UISearchBarIcon

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

此外,要更改 searchBar 图标,您可以使用以下内置方法UISearchBar(可从iOS 5+获得):

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

在这里您可以设置4种类型的UISearchBarIconie:

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

我希望这可以帮助你...

于 2012-12-11T10:08:55.140 回答
24

根据UISearchBar 文档

您应该在 iOS 5.0+ 上使用此功能。

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

使用示例:

[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];

可悲的是,在 iOS 4 中,您需要恢复到不太复杂的方法。查看其他答案。

于 2012-12-11T10:33:18.800 回答
20

正如 Accatyyc 所说,对于 iOS5+ 使用 setSearchFieldBackgroundImage,但您要么需要创建图形,要么执行以下操作:

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];
于 2014-03-08T06:38:06.527 回答
17

苹果的方式呢?

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

您可以在设计上设置任何图像!

但是如果你想创建所有程序,你可以这样做


我在Swift 3上的解决方案

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

我在哪里使用助手扩展

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

}
于 2017-03-24T22:43:14.817 回答
14

要在 iOS 13+ 上执行此操作,

searchController.searchBar.searchTextField.backgroundColor = // your color here

请注意,默认情况下searchTextField.borderStyle设置为roundedRect,这会在您将设置的颜色之上应用轻微的灰色覆盖。如果这是不希望的,请执行

searchController.searchBar.searchTextField.borderStyle = .none

这将摆脱灰色覆盖,但也摆脱了圆角。

于 2019-08-29T20:34:44.467 回答
7

我发现这是使用 Swift 2.2 和 iOS 8+ 自定义各种搜索栏属性外观的最佳方式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

在此处输入图像描述

于 2016-05-16T18:31:55.083 回答
6

不使用私有 API:

for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) {
    if ([subview isKindOfClass:[UITextField class]]) {
        UITextField *textField = (UITextField*)subview;
        [textField setBackgroundColor:[UIColor redColor]];
    }
}
于 2013-11-07T12:39:41.770 回答
5

仅更改颜色:

searchBar.tintColor = [UIColor redColor];

对于应用背景图像:

[self.searchBar setSearchFieldBackgroundImage:
                          [UIImage imageNamed:@"Searchbox.png"]
                                     forState:UIControlStateNormal];
于 2013-07-08T13:04:49.963 回答
5

更好的解决方案是设置UITextField里面的外观UISearchBar

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:[UIColor grayColor]];
于 2015-05-27T13:17:42.450 回答
5

在 iOS13 中快速尝试这个

@IBOutlet weak var searchBar: UISearchBar!
searchBar.barTintColor = .systemIndigo
searchBar.searchTextField.backgroundColor = .white
于 2020-08-20T11:33:57.127 回答
4

只需使用类别方法遍历所有视图(在 iOS 7 中验证并且不使用私有 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

因此,将类别导入您的课程后,只需像这样使用它:

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

请记住,如果您将其立即放在该[[UISearchBar alloc] init]行之后,它还不会起作用,因为搜索栏的子视图仍在创建中。设置搜索栏的其余部分后,将其放下几行。

于 2014-04-06T04:06:36.513 回答
3
- (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;
}
于 2014-10-09T09:55:47.610 回答
3

这是 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()
        }
    }
}
于 2015-11-09T04:26:57.843 回答
2

iOS 13、斯威夫特 5

searchBar.searchTextField.backgroundColor = .gray
 searchBar.searchTextField.tintColor = .white
 searchBar.searchTextField.textColor = .white
于 2019-10-02T13:45:57.253 回答
2

Searchbar 现在有一个新的实例属性 SearchTextField 从 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]];
}
于 2019-11-27T06:41:00.390 回答
1

对于 iOS 9,请使用:

- (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;
}
于 2015-11-01T18:26:16.810 回答
1

斯威夫特 3

for subview in searchBar.subviews {
    for innerSubview in subview.subviews {
        if innerSubview is UITextField {
            innerSubview.backgroundColor = UIColor.YOUR_COLOR_HERE
        }
    }
}
于 2017-01-15T17:57:58.843 回答
1

对于 Swift 3+,使用这个:

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
        }
     }
}
于 2017-03-31T08:54:22.257 回答
1

使用 Swift 4,我建议你只这样做,不需要额外的代码:

self.searchBar.searchBarStyle = .prominent
self.searchBar.barStyle = .black

如果您不希望外部背景为灰色,您也可以将 .prominent 更改为 .minimal。

于 2019-01-19T11:25:13.687 回答
0

@EvGeniy Ilyin EvGeniy Ilyin 的解决方案是最好的。我基于这个解决方案 编写了一个Objective-C版本。

创建一个UIImage类别,并在UIImage+YourCategory.h中宣传两个类方法

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

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

做你自己UISearchBarViewController

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];
于 2017-10-12T01:26:57.733 回答
0

这对我有用。

- (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]];
}
于 2018-10-23T05:46:53.570 回答
0

使用它来更新 xcode10 和 xcode11 的搜索文本字段 backgroud_color 对我来说工作正常

[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor greenColor]];
于 2020-01-20T12:19:46.730 回答
-1

这帮助我更改了搜索栏中 textField 的背景颜色。

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .white
于 2019-02-07T10:35:10.543 回答