简体   繁体   English

无法更改搜索栏背景颜色

[英]Cannot change search bar background color

I have a search bar:我有一个搜索栏:

let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24))

and I want to change text input part background color.我想更改文本输入部分的背景颜色。 For this I've tried:为此,我尝试过:

searchBar.barTintColor = UIColor(red: 0/255, green: 74/255, blue: 103/255, alpha: 1)

searchBar.backgroundColor = UIColor.redColor()

but these both variants do not work.但是这两种变体都不起作用。 How can I change background color of my UISearchBar textInput part and what I did wrong?如何更改 UISearchBar textInput 部分的背景颜色以及我做错了什么?

Like @aliamcami, all the answers before did not work as I would expect, either the answer did not work for me or it works but it needs too much "dummy" code.像@aliamcami 一样,之前的所有答案都没有像我预期的那样有效,要么答案对我不起作用,要么有效,但它需要太多“虚拟”代码。 So I share another answer wrote in Swift 4 with simplified logic:所以我分享了另一个在Swift 4中用简化逻辑编写的答案:

for textField in searchController.searchBar.subviews.first!.subviews where textField is UITextField {
    textField.subviews.first?.backgroundColor = .white
    textField.subviews.first?.layer.cornerRadius = 10.5 //I set 10.5 because is approximately the system value
    textField.subviews.first?.layer.masksToBounds = true
    //Continue changing more properties...
}

textField.subviews.first is the "_UISearchBarSearchFieldBackgroundView" subview which add visual effects behind the UIFieldEditor . textField.subviews.first是“_UISearchBarSearchFieldBackgroundView”子视图,它在UIFieldEditor后面添加视觉效果。


Edited已编辑

After some development and many bugs, I finished with this elegant solution (that I am sure Apple would not be happy to approve, but I do not know) that works from iOS 10 to iOS 12 :经过一些开发和许多错误之后,我完成了这个从iOS 10iOS 12 都有效的优雅解决方案(我相信 Apple 不会乐意批准,但我不知道):

if let textField = searchBar.value(forKey: "searchField") as? UITextField {
    textField.backgroundColor = myColor
    //textField.font = myFont
    //textField.textColor = myTextColor
    //textField.tintColor = myTintColor
    // And so on...
    
    let backgroundView = textField.subviews.first
    if #available(iOS 11.0, *) { // If `searchController` is in `navigationItem`
        backgroundView?.backgroundColor = UIColor.white.withAlphaComponent(0.3) //Or any transparent color that matches with the `navigationBar color`
        backgroundView?.subviews.forEach({ $0.removeFromSuperview() }) // Fixes an UI bug when searchBar appears or hides when scrolling
    }
    backgroundView?.layer.cornerRadius = 10.5
    backgroundView?.layer.masksToBounds = true
    //Continue changing more properties...
}

When the searchBar is in the tableHeaderView the above code can be called in viewWillAppear , but if it is in the navigationItem on iOS 11 and above it should be called in viewDidAppear .searchBartableHeaderView ,上面的代码可以在viewWillAppear调用,但如果它在 iOS 11 及更高版本的navigationItem ,则应在viewDidAppear调用。

If you only want to change it in your ViewController and don't want anywhere else to effect then use如果您只想在 ViewController 中更改它并且不想在其他任何地方生效,请使用

for view in searchBar.subviews {
            for subview in view.subviews {
                if subview .isKindOfClass(UITextField) {
                    let textField: UITextField = subview as! UITextField
                    textField.backgroundColor = UIColor.redColor()
                }
            }
        }

But if you want it to be change in whole app and targeting the iOS 9.0 or later then should be using appearanceWhenContainedInInstancesOfClasses like但是,如果您希望它在整个应用程序中进行更改并针对 iOS 9.0 或更高版本,则应该使用 AppearanceWhenContainedInInstancesOfClasses 之类的

UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.redColor()

I did one UISearchBar extension & category for customize text filed within search bar.我做了一个 UISearchBar 扩展和类别来自定义搜索栏中的文本。

Compatible from iOS 9 to iOS 13.兼容从 iOS 9 到 iOS 13。

Swift 4+斯威夫特 4+

import UIKit

extension UISearchBar {

    // Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility
    var compatibleSearchTextField: UITextField {
        guard #available(iOS 13.0, *) else { return legacySearchField }
        return self.searchTextField
    }

    private var legacySearchField: UITextField {
        if let textField = self.subviews.first?.subviews.last as? UITextField {
            // Xcode 11 previous environment
            return textField
        } else if let textField = self.value(forKey: "searchField") as? UITextField {
            // Xcode 11 run in iOS 13 previous devices
            return textField
        } else {
            // exception condition or error handler in here
            return UITextField()
        }
    }
}

Usage Example:用法示例:

var searchController: UISearchController?
searchController?.searchBar.compatibleSearchTextField.textColor = UIColor.XXX
searchController?.searchBar.compatibleSearchTextField.backgroundColor = UIColor.XXX

Objective-C目标-C

UISearchBar+SearchTextField.h UISearchBar+SearchTextField.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UISearchBar (SearchTextField)

// Due to searchTextField property who available iOS 13 only, extend this property for iOS 13 previous version compatibility
@property (nonatomic, readonly) UITextField *compatibleSearchTextField;

@end

NS_ASSUME_NONNULL_END

UISearchBar+SearchTextField.m UISearchBar+SearchTextField.m

#import "UISearchBar+SearchTextField.h"

@implementation UISearchBar (SearchTextField)

- (UITextField *)compatibleSearchTextField {
    if (@available(iOS 13.0, *)) {
#ifdef __IPHONE_13_0
        return self.searchTextField;
#else
        // Xcode 11 run in iOS 13 previous devices
        return (UITextField *)[self valueForKey:@"searchField"];
#endif
    } else {
        // Xcode 11 previous environment
        return [[[self.subviews firstObject] subviews] lastObject];
    }
}

@end

Usage Example:用法示例:

- (UISearchBar *)searchBar {
    if (!_searchBar) {
        _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(X, X, X, X)];
        _searchBar.compatibleSearchTextField.textColor = [UIColor XXX];
        _searchBar.compatibleSearchTextField.backgroundColor = [UIColor XXX];
    }
    return _searchBar
}

You are adding the below code in ViewDidLoad and Change the textfield background color RED,您在 ViewDidLoad 中添加以下代码并将文本字段背景颜色更改为红色,

for subView in searchBar.subviews
{
    for subView1 in subView.subviews
    {

        if subView1.isKindOfClass(UITextField)
        {
            subView1.backgroundColor = UIColor.redColor()
        }
    }

}

Red Color of TextField in SearchBar. SearchBar 中 TextField 的红色。

在此处输入图片说明

For Swift 3+, use this:对于 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
        }
     }
}

斯威夫特 5:

    searchController.searchBar.searchTextField.backgroundColor = .white

The way to do this only using Apple APIs is to create an image and use setSearchFieldBackgroundImage :仅使用 Apple API 执行此操作的方法是创建一个图像并使用setSearchFieldBackgroundImage

self.searchBar.setSearchFieldBackgroundImage(UIImage(named: "SearchFieldBackground"), for: UIControlState.normal)

It will even animate the corners properly if you create a rounded rect and dynamically show and hide buttons.如果您创建圆角矩形并动态显示和隐藏按钮,它甚至可以正确地为角设置动画。

Example using this image:使用此图像的示例: 在此处输入图片说明

在此处输入图片说明

Faced the same issue , for iOS 13+ , textFiled can be get by as follow面临同样的问题,对于iOS 13+ ,textFiled 可以通过如下方式获得

var searchText : UITextField?
if #available(iOS 13.0, *) {
   searchText  = searchBar.searchTextField
}
else {
    searchText = searchBar.value(forKey: "_searchField") as? UITextField
}
searchText?.backgroundColor = .red                                                              

Swift 5 extension:斯威夫特 5扩展:

Works perfect on all iOS versions适用于所有 iOS 版本

import UIKit

extension UISearchBar {

    func setupSearchBar(background: UIColor = .white, inputText: UIColor = .black, placeholderText: UIColor = .gray, image: UIColor = .black) {

        self.searchBarStyle = .minimal

        self.barStyle = .default

        // IOS 12 and lower:
        for view in self.subviews {

            for subview in view.subviews {
                if subview is UITextField {
                    if let textField: UITextField = subview as? UITextField {

                        // Background Color
                        textField.backgroundColor = background

                        //   Text Color
                        textField.textColor = inputText

                        //  Placeholder Color
                        textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "", attributes: [NSAttributedString.Key.foregroundColor : placeholderText])

                        //  Default Image Color
                        if let leftView = textField.leftView as? UIImageView {
                            leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
                            leftView.tintColor = image
                        }

                        let backgroundView = textField.subviews.first
                        backgroundView?.backgroundColor = background
                        backgroundView?.layer.cornerRadius = 10.5
                        backgroundView?.layer.masksToBounds = true

                    }
                }
            }

        }

        // IOS 13 only:
        if let textField = self.value(forKey: "searchField") as? UITextField {

            // Background Color
            textField.backgroundColor = background

            //   Text Color
            textField.textColor = inputText

            //  Placeholder Color
            textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "", attributes: [NSAttributedString.Key.foregroundColor : placeholderText])

            //  Default Image Color
            if let leftView = textField.leftView as? UIImageView {
                leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
                leftView.tintColor = image
            }

        }

    }

}

Just like this像这样

let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24))
let searchTextField = searchBar.valueForKey("_searchField") as? UITextField
searchTextField?.backgroundColor = UIColor.redColor()

I do it with this way(Swift 3+ solution):我用这种方式(Swift 3+ 解决方案):

let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.backgroundColor = UIColor.red

I was experimenting with the properties of searchBar and searchTextField when I found a solution to the above.当我找到上述问题的解决方案时,我正在试验 searchBar 和 searchTextField 的属性。

Below, I have listed the steps in order to achieve the desired result:下面,我列出了实现预期结果的步骤:

  1. Set the border style of the searchTextField to .none将searchTextField的边框样式设置为.none
  2. Set the background color of the searchTextField to your desired color将 searchTextField 的背景颜色设置为您想要的颜色
  3. Change the corner radius of the searchTextField's layer to 10将searchTextField的图层的角半径更改为10
  4. Set the searchTextField's clipToBounds property to true将 searchTextField 的 clipToBounds 属性设置为 true

Further, I have provided the code below for your reference:此外,我提供了以下代码供您参考:

 let searchController = UISearchController(searchResultsController: nil)
 navigationItem.searchController = searchController

 searchController.searchBar.barTintColor = viewBackgroundColor
 searchController.searchBar.backgroundColor = viewBackgroundColor

 searchController.searchBar.searchTextField.borderStyle = .none
 searchController.searchBar.searchTextField.backgroundColor = .white
 searchController.searchBar.searchTextField.layer.cornerRadius = 10
 searchController.searchBar.searchTextField.clipsToBounds = true

Note: searchTextField is in Beta and available on iOS 13注意:searchTextField 处于 Beta 版,可在 iOS 13 上使用

FWIW I'm solving this problem by creating a computed variable named textField. FWIW 我通过创建一个名为 textField 的计算变量来解决这个问题。

extension UISearchBar {
    var textField: UITextField? {
        return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField
    }
}

A very common answer to this question on the web is this solution described above:网络上这个问题的一个非常常见的答案是上面描述的这个解决方案:

for subView in searchBar.subviews {
    for subViewInSubView in subView.subviews {   
        if subViewInSubView.isKindOfClass(UITextField) {
            subViewInSubView.backgroundColor = UIColor.purpleColor()
       }
    }
}

But it didn't work for me using XCode 7 and iOS 9, and I noticed that around the web many others reported that it didn't work for them, either.但是它对我使用 XCode 7 和 iOS 9 不起作用,我注意到网络上的许多其他人报告说它对他们也不起作用。 I discovered that the UITextField subview isn't created (or at least it isn't added as a subview) until it is referenced, and one way it can be referenced is by the placeholder field, eg, one could add this line before searching the subviews for the UITextField class:我发现 UITextField 子视图在被引用之前不会被创建(或者至少它没有被添加为子视图),并且可以引用它的一种方式是通过占位符字段,例如,可以在搜索之前添加这一行UITextField 类的子视图:

searchBar.placeholder = searchBar.placeholder

Search Bar Color Change搜索栏颜色变化

Simply change the searchbar style to minimal and it will show the search bar's background color.只需将搜索栏样式更改为最小,它就会显示搜索栏的背景颜色。 To change the oval inside the box aka the textfield.更改框内的椭圆形,即文本字段。 Just change the searchbar.textfield.backgroundcolor attribute.只需更改 searchbar.textfield.backgroundcolor 属性。

 searchbar.searchBarStyle = .minimal
 searchbar.backgroundColor = //color here                  
 searchbar.searchTextField.backgroundColor = //color here     

Here's the solution:这是解决方案:

func customizeSearchBar(){
    if let textfield = searchController.searchbar.value(forKey: "searchField") as? UITextField {
        textfield.textColor = UIColor.blue
        if let backgroundview = textfield.subviews.first {

            // Background color
            backgroundview.backgroundColor = UIColor.white

            // Rounded corner
            backgroundview.layer.cornerRadius = 10;
            backgroundview.clipsToBounds = true;
        }
    }
}

But Please note that this works only in iOS 11.0 and later.但请注意,这仅适用于 iOS 11.0 及更高版本。 So don't forget to add before that所以不要忘记在此之前添加

if #available(iOS 11.0, *) {}

Set any color you want.设置您想要的任何颜色 SWIFT 3斯威夫特 3

public extension UISearchBar {
  public func setStyleColor(_ color: UIColor) {
    tintColor = color
    guard let tf = (value(forKey: "searchField") as? UITextField) else { return }
    tf.textColor = color
    if let glassIconView = tf.leftView as? UIImageView, let img = glassIconView.image {
      let newImg = img.blendedByColor(color)
      glassIconView.image = newImg
    }
    if let clearButton = tf.value(forKey: "clearButton") as? UIButton {
      clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal)
      clearButton.tintColor = color
    }
  }
}

extension UIImage {

  public func blendedByColor(_ color: UIColor) -> UIImage {
    let scale = UIScreen.main.scale
    if scale > 1 {
      UIGraphicsBeginImageContextWithOptions(size, false, scale)
    } else {
      UIGraphicsBeginImageContext(size)
    }
    color.setFill()
    let bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    UIRectFill(bounds)
    draw(in: bounds, blendMode: .destinationIn, alpha: 1)
    let blendedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return blendedImage!
  }
}

A UISearchBar extension using Swift 4 based on the most voted answer基于投票最多的答案使用 Swift 4 的 UISearchBar 扩展

extension UISearchBar {

    func tfBackgroundColor(color: UIColor){
        for view in self.subviews {
            for subview in view.subviews {
                if subview is UITextField {
                    let textField: UITextField = subview as! UITextField
                    textField.backgroundColor = color
                }
            }
        }
    }
    }

Just try your code as below in playground.只需在操场上尝试您的代码,如下所示。 If still that won't work, add more code to your question...如果仍然不起作用,请在您的问题中添加更多代码...

let searchView = UIView(frame: CGRect(x: 0.0,y: 0.0, width: 100, height: 50))

let searchBar:UISearchBar = UISearchBar(frame: CGRectMake((searchView.frame.width - UIScreen.mainScreen().bounds.width / 1.6) / 2, 0, UIScreen.mainScreen().bounds.width / 1.6, 24))

for subView in searchBar.subviews {
    for subViewInSubView in subView.subviews {   
        if subViewInSubView.isKindOfClass(UITextField) {
            subViewInSubView.backgroundColor = UIColor.purpleColor()
        }
    }
}

I just came to share the ONLY way I could change the background color for the searchbar textField because I havent seen it on any answer yet, and none of the other suggestions, here or the in other sites, have worked for me.我只是来分享我可以更改搜索栏 textField 背景颜色的唯一方法,因为我还没有在任何答案中看到它,而且这里或其他网站的其他建议都没有对我有用。

  • Get the textField from the search bar, like the answer from @Steve ... anything works here as long as you get the textField.从搜索栏中获取 textField,就像@Steve 的回答一样......只要你得到 textField,任何事情都可以在这里工作。 This was not my problem, the thing is, it did not metter the colors I setted here, it was not working extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } }这不是我的问题,问题是,它没有符合我在这里设置的颜色,它不起作用extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } } extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } }

  • Make a new layer with the size of the navigationBar let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor //Set your color here layer.frame = navigationBar.frame用导航let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor //Set your color here layer.frame = navigationBar.frame的大小新建一个图层let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor //Set your color here layer.frame = navigationBar.frame

  • Set the new layer as sublayer for textfield navigationBar.textField?.layer.masksToBounds = true //to make sure you get the rounded corners navigationBar.textField?.layer.cornerRadius = 14 //Round it as you wish navigationBar.textField?.layer.addSublayer(layer)将新图层设置为 textfield navigationBar.textField?.layer.masksToBounds = true //to make sure you get the rounded corners navigationBar.textField?.layer.cornerRadius = 14 //Round it as you wish navigationBar.textField?.layer.addSublayer(layer)子图层navigationBar.textField?.layer.masksToBounds = true //to make sure you get the rounded corners navigationBar.textField?.layer.cornerRadius = 14 //Round it as you wish navigationBar.textField?.layer.addSublayer(layer)
  • thats it, you will have an rounded textField background with any color you want.就是这样,您将拥有一个带有您想要的任何颜色的圆形 textField 背景。

Here's the solution这是解决方案

func configureSearchBar() {
    for textField in searchBar.subviews.first!.subviews where textField is UITextField {
        textField.backgroundColor = .cyan
    }
}

Swift 5 中,只需输入这个 sh.ts :) :D

self.personelSearchBar.searchTextField.backgroundColor = .white self.personelSearchBar.searchTextField.layer.borderWidth = 0.5 self.personelSearchBar.searchTextField.layer.cornerRadius = 3 self.personelSearchBar.searchTextField.layer.borderColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3).cgColor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM