【问题标题】:Cannot change search bar background color无法更改搜索栏背景颜色
【发布时间】:2016-02-18 11:46:37
【问题描述】:

我有一个搜索栏:

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

我想更改文本输入部分的背景颜色。为此我尝试过:

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

searchBar.backgroundColor = UIColor.redColor()

但这两种变体都不起作用。如何更改 UISearchBar textInput 部分的背景颜色以及我做错了什么?

【问题讨论】:

  • 查看演示项目,我在 StoryBoard 中添加了 SearchBar。
  • 我想更改圆形文本字段周围的颜色,并尝试了以下所有解决方案:D,但这只是您在上面尝试的barTintColor 属性。确保在代码或情节提要中将isTranslucent 设置为false

标签: ios swift uisearchbar


【解决方案1】:

像@aliamcami 一样,之前的所有答案都没有像我预期的那样起作用,要么答案对我不起作用,要么它起作用但它需要太多“虚拟”代码。所以我用简化的逻辑分享另一个用 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 是“_UISearchBarSearchFieldBackgroundView”子视图,在UIFieldEditor 后面添加视觉效果。


已编辑

经过一些开发和许多错误,我完成了这个 优雅 解决方案(我确信 Apple 不会乐意批准,但我不知道),它适用于 iOS 10 iOS 12

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

searchBartableHeaderView中时,上面的代码可以在viewWillAppear中调用,但如果在iOS 11及更高版本的navigationItem中,则应在viewDidAppear中调用。

【讨论】:

  • @Ángel Téllez 提供的解决方案也对我有用!谢谢天使!不确定它是否也适用于 IOS 10,但它适用于 11。此外,有一个小的 UI 故障,用于闪烁(在一秒钟内),导航标题和搜索栏控制器之间出现一条白线。不知道为什么会发生这种情况,但很高兴这有效!
  • 不客气,@sudhama。我很高兴它至少对某人有用:D。我在 3 个月后完成了一些修复后更新了我的答案。该代码适用于我在 iOS 10 及更高版本(从 iPhone 5 到 XS)中的工作。关于故障,可能是您必须更改searchBarviewWillAppear 的属性?或者您可能正在玩弄searchBarshadowImage 属性,这会导致它下面的行重新加载?我希望你能解决它:)
  • 为了避免搜索栏在navigationItem而不是viewDidAppear时搜索栏短暂闪烁旧颜色,我发现我可以在调用后将它放在viewDidLayoutSubviewssuper
【解决方案2】:

如果您只想在 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()
                }
            }
        }

但是,如果您希望它在整个应用程序中进行更改并以 iOS 9.0 或更高版本为目标,那么应该使用像

这样的外观时包含InInstancesOfClasses
UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).backgroundColor = UIColor.redColor()

【讨论】:

  • 不知道为什么,还是不变色
【解决方案3】:

我做了一个 UISearchBar 扩展和类别来自定义搜索栏中的文本。

从 iOS 9 兼容到 iOS 13。

斯威夫特 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()
        }
    }
}

使用示例:

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

目标-C

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

#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

使用示例:

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

【讨论】:

    【解决方案4】:

    仅使用 Apple API 的方法是创建图像并使用 setSearchFieldBackgroundImage

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

    如果您创建一个圆角矩形并动态显示和隐藏按钮,它甚至可以正确地为角设置动画。

    使用此图片的示例:

    【讨论】:

    • 这与在searchBar 上设置backgroundColor 相同。只是不必要地复杂并且不能解决色调问题,因为您无法正确更改文本色调或文本字段背景以匹配背景
    • backgroundColor 对我没有任何改变
    • 它并没有不必要的复杂,它是正确使用的 API。
    • 我无法在 ios 12 中更改 navigationItem bg 颜色。一直播放白色。在 ios13 中工作正常。在我的情况下想要设置粉红色。
    【解决方案5】:

    您在 ViewDidLoad 中添加以下代码并将文本字段背景颜色更改为红色,

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

    SearchBar 中 TextField 的颜色为红色。

    【讨论】:

    • 我不知道为什么,但是我尝试了很多解决方案,但没有一个适合我=/
    • 以上demo项目下载并实现与你项目中的demo一样。
    • 取消选中搜索栏属性中的“半透明”,而不是上面的代码。
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      斯威夫特 5:

          searchController.searchBar.searchTextField.backgroundColor = .white
      

      【讨论】:

      • 这应该是公认的答案。 1 条线,按预期完美运行。没有什么花哨的,也没有解决方法。此线程上的最佳答案
      • 这将在 iOS 12.x 下崩溃,这就是其他答案更合适的原因。
      【解决方案8】:

      我是这样做的(Swift 3+ 解决方案):

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

      【讨论】:

      • 这是唯一适用于 Xcode 11 的。谢谢!
      【解决方案9】:

      遇到同样的问题,对于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                                                              
      

      【讨论】:

      • 不错的答案。简单直接。
      【解决方案10】:

      Swift 5 扩展:

      适用于所有 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
                  }
      
              }
      
          }
      
      }
      

      【讨论】:

        【解决方案11】:

        就这样

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

        【讨论】:

          【解决方案12】:

          当我找到上述问题的解决方案时,我正在试验 searchBar 和 searchTextField 的属性。

          下面,我列出了达到预期结果的步骤:

          1. 将 searchTextField 的边框样式设置为 .none
          2. 将 searchTextField 的背景颜色设置为您想要的颜色
          3. 将searchTextField层的圆角半径改为10
          4. 将 searchTextField 的 clipToBounds 属性设置为 true

          此外,我提供了以下代码供您参考:

           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
          
          

          注意:searchTextField 处于测试阶段,可在 iOS 13 上使用

          【讨论】:

            【解决方案13】:

            FWIW 我正在通过创建一个名为 textField 的计算变量来解决这个问题。

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

            【讨论】:

              【解决方案14】:

              网络上这个问题的一个非常常见的答案是上面描述的这个解决方案:

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

              但它对我使用 XCode 7 和 iOS 9 不起作用,而且我注意到在网络上许多其他人报告说它对他们也不起作用。我发现 UITextField 子视图在被引用之前没有创建(或者至少它没有作为子视图添加),并且可以引用它的一种方式是通过占位符字段,例如,可以在搜索之前添加这一行UITextField 类的子视图:

              searchBar.placeholder = searchBar.placeholder
              

              【讨论】:

              • 在搜索子视图之前添加占位符对我来说很重要,很好!
              【解决方案15】:

              搜索栏颜色变化

              只需将搜索栏样式更改为最小,它就会显示搜索栏的背景颜色。更改框内的椭圆形,即文本字段。只需更改 searchbar.textfield.backgroundcolor 属性即可。

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

              【讨论】:

                【解决方案16】:

                解决办法如下:

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

                但请注意,这仅适用于 iOS 11.0 及更高版本。 所以不要忘记在此之前添加

                if #available(iOS 11.0, *) {}
                

                【讨论】:

                  【解决方案17】:

                  设置您想要的任何颜色SWIFT 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!
                    }
                  }
                  

                  【讨论】:

                    【解决方案18】:

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

                    【讨论】:

                      【解决方案19】:

                      只需在操场上尝试您的代码,如下所示。如果仍然无法解决问题,请在您的问题中添加更多代码...

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

                      【讨论】:

                        【解决方案20】:

                        我只是来分享我可以更改搜索栏 textField 的背景颜色的唯一方法,因为我还没有在任何答案上看到它,而且这里或其他网站中的其他建议都没有对我有用。

                        • 从搜索栏中获取 textField,就像 @Steve 的答案一样......只要你得到 textField,任何东西都可以在这里工作。这不是我的问题,问题是,它不符合我在这里设置的颜色,它不起作用 extension UISearchBar { var textField: UITextField? { return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField } }

                        • 新建一个与导航栏大小相同的层 let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor //Set your color here layer.frame = navigationBar.frame

                        • 将新图层设置为文本字段的子图层 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)
                        • 就是这样,您将拥有一个带有任何颜色的圆形文本字段背景。

                        【讨论】:

                          【解决方案21】:

                          解决办法

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

                          【讨论】:

                            【解决方案22】:

                            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

                            【讨论】:

                              猜你喜欢
                              • 2018-07-31
                              • 1970-01-01
                              • 2020-12-17
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2013-10-10
                              • 2016-07-24
                              • 1970-01-01
                              相关资源
                              最近更新 更多