【问题标题】:How to change background color of the text field in the UISearchController?如何更改 UISearchController 中文本字段的背景颜色?
【发布时间】:2018-12-13 13:06:41
【问题描述】:

如何更改 UISearchController 搜索文本字段的默认灰色背景?

【问题讨论】:

标签: ios swift ios11 uisearchcontroller


【解决方案1】:

这是一个关于如何设置textField 背景的示例。

class ViewController: UIViewController {

    let searchController = UISearchController(searchResultsController: nil)

    private lazy var searchTextField: UITextField? = { [unowned self] in
        var textField: UITextField?
        self.searchController.searchBar.subviews.forEach({ view in
            view.subviews.forEach({ view in
                if let view  = view as? UITextField {
                    textField = view
                }
            })
        })
        return textField
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search Candies"
        navigationItem.searchController = searchController
        definesPresentationContext = true

        if let bg = self.searchTextField?.subviews.first {
            bg.backgroundColor = .green
            bg.layer.cornerRadius = 10
            bg.clipsToBounds = true
        }
    }
}

结果

【讨论】:

  • 不是找到UITextField 的最佳方式。至少让它递归。 :(
【解决方案2】:

更新 UISearchController 背景的正确方法是改变背景图片。

如果你在可视化调试器中看到 UISearchController 你会发现它的背景是 UIImageView:

所以你应该制作你的搜索栏的小图像并将其设置为 seachBar 像这样:

    lazy var searchController: UISearchController = {

        let searchController = UISearchController(searchResultsController: nil)

        searchController.searchBar.placeholder = "Search"
        searchController.searchBar.tintColor = UIColor.black
        searchController.searchBar.searchBarStyle = .minimal
        // Set background image to searchBar so it will resize
        searchController.searchBar.setSearchFieldBackgroundImage(UIImage(named: "oval_static"), for: .normal)

        definesPresentationContext = true

        return searchController
    }()

searchBar的图片(项目中我推荐使用.pdf或.png格式的图片,这里只是截图):

UISearchBar 会根据需要调整它的大小,结果是:

此外,我们可以这样做以仅在代码中创建自定义背景:

/// Just random extension to make image from UIView, you can use your own
extension UIView {

func asImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(bounds: bounds)
    return renderer.image { rendererContext in
        layer.render(in: rendererContext.cgContext)
    }
}}

lazy var searchController: UISearchController = {

        let searchController = UISearchController(searchResultsController: nil)

        searchController.searchBar.placeholder = "Search"
        searchController.searchBar.tintColor = UIColor.black
        searchController.searchBar.searchBarStyle = .minimal

        // Create own view with custom properties
        // Default height is 36 points
        let differentColorSearchBar = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 36))

        differentColorSearchBar.layer.cornerRadius = 8
        differentColorSearchBar.clipsToBounds = true
        differentColorSearchBar.backgroundColor = UIColor.blue

        searchController.searchBar.setSearchFieldBackgroundImage(differentColorSearchBar.asImage(), for: .normal)

        definesPresentationContext = true

        return searchController
    }

结果是(当然你可以改变 searchBar 的另一个属性让它变得更好,但我只是告诉你如何正确改变背景):

我建议避免使用私有属性,只使用 open!希望有帮助。

【讨论】:

    【解决方案3】:

    在 iOS13 及更高版本上,searchTextField 是 UISearchBar 的成员。所以你可以使用这样的东西:

    searchController.searchBar.searchTextField.backgroundColor = UIColor.blue
    

    请注意,Apple 在 SDK 中没有适当的符号显示此属性是在 iOS 13 中引入的,因此如果您支持 iOS 12 或更早版本,它不会向您显示任何警告。确保仅针对 iOS 13 进行包装。

    【讨论】:

      【解决方案4】:

      我是这样做的,Objective-C代码:

      UITextField *searchField = [_navigationSearchBar valueForKey:@"searchField"];
      searchField.backgroundColor = [UIColor defaultSeacrhBarColor];
      searchField.textColor = [UIColor defaultWhiteColor];
      searchField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:searchTitle];
      UILabel *placeholderLabel = [searchField valueForKey:@"placeholderLabel"];
      placeholderLabel.textColor = [UIColor lightTextColor];
      
      UIButton *clearButton = [searchField valueForKey:@"clearButton"];
      [clearButton setImage:[clearButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
      clearButton.tintColor = [UIColor defaultWhiteColor];
      
      _navigationSearchBar.delegate = self;
      [_navigationSearchBar setTranslucent:NO];
      [_navigationSearchBar setBackgroundImage:nil];
      [_navigationSearchBar setBarTintColor:[UIColor defaultNavigationBarColor]];
      [_navigationSearchBar setBackgroundColor:[UIColor defaultNavigationBarColor]];
      [_navigationSearchBar setImage:[UIImage imageNamed:@"Search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
      _navigationSearchBar.clipsToBounds = YES;
      [_navigationBar addSubview:_navigationSearchBar];
      

      【讨论】:

        【解决方案5】:

        最多使用下面这个函数来改变颜色。

        extension UISearchBar {
          func setBackgroundColor(){
            if let view:UIView = self.subviews.first {
                for curr in view.subviews {
                    guard let searchBarBackgroundClass = NSClassFromString("UISearchBarBackground") else {
                        return
                    }
                    if curr.isKind(of:searchBarBackgroundClass){
                        if let imageView = curr as? UIImageView{
                            imageView.backgroundColor = .red
                            break
                        }
                    }
                }
            }
          }
        }
        

        将此功能与搜索栏一起使用。

        searchBarController.searchBar.setBackgroundColor()
        

        【讨论】:

          【解决方案6】:

          Apple 有键 'searchField' 来检测 searchBar 中的文本字段。因此,首先安全地获取该文本字段并使用文本字段进行任何您想要的更改。

          let searchController = UISearchController(searchResultsController: nil)
          searchController.searchResultsUpdater = self
          searchController.searchBar.placeholder = "Search here..."
          searchController.searchBar.delegate = self
          searchController.searchBar.tintColor = .white
          searchController.searchBar.barTintColor = .white
          searchController.hidesNavigationBarDuringPresentation = false
          searchController.obscuresBackgroundDuringPresentation = false
          
          if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {
          
              // Set text colour of text field   
              textfield.textColor = UIColor.blue
          
              if let backgroundview = textfield.subviews.first {
          
                  // Get background view and change background color
                  backgroundview.backgroundColor = UIColor.white
          
                  // Set rounded corner
                  backgroundview.layer.cornerRadius = 10
                  backgroundview.clipsToBounds = true
              }
          }
          
          if #available(iOS 11.0, *) {
              self.navigationItem.searchController = searchController
          } else {
              self.tblCustomers.tableHeaderView = searchController.searchBar
          }
          

          这是工作代码,我已在当前​​项目中实现。如果您有任何疑问,请告诉我。

          希望对你有帮助。

          【讨论】:

          • 当你写 .value(forKey: "searchField") 时,你是在打电话给 Apple,在他们注意到时拒绝你的应用程序。此外,如果他们只是在任何新版本中重命名 searchField 属性,您的应用程序将会崩溃。
          • @Kamran,首先,我通过if let 的可选解包安全地获取了textField,所以它不会崩溃应用程序。第二件事,如果应用程序处于活动状态,那么它将如何崩溃。此外,我的一个应用程序已经存在于此代码可用的地方。
          • 是的,如果.value(forKey: "searchField") 没有崩溃,可选的展开将起作用。如果它在这个方法里面崩溃了,可选的 unwrap 也救不了你。如果应用程序处于活动状态并且他们在新操作系统中重命名了该属性,那么它将开始崩溃,因为该密钥将不可用。最后,您的应用程序和许多其他应用程序都已上线,因为 Apple 没有注意到您正在访问 private api。只要他们注意到这一点,就可以拒绝该应用。
          【解决方案7】:

          没有任何适当/公开的方法可以更改此搜索栏的背景颜色。有一些方法可以使用私有 api,例如 @sanjayshah 的回答,但在这种情况下,苹果可能会拒绝您的申请。我认为您应该继续使用默认背景颜色。大多数应用程序使用相同。

          【讨论】:

            【解决方案8】:

            @Kamran 答案的递归版本,具有更好的最佳情况和平均运行时间。接受的版本不适用于我的 iOS 13+。

            private lazy var searchTextField: UITextField? = { [unowned self] in
                guard let searchBar = self.searchController?.searchBar else { return nil }
                var views =  searchBar.subviews
                while !views.isEmpty {
                    guard let view = views.popLast() else { break }
                    if let textfield = view as? UITextField {
                        return textfield
                    }
                    views += view.subviews
                }
                return nil
            }()
            

            【讨论】:

              【解决方案9】:

              首先检查平台,

              比起修改,导致 IOS 13 不接受为 IOS 12 制作的很多技巧

              if #available(iOS 13, *) {
                 searchController.searchBar.searchTextField.backgroundColor = .white 
              } else {
              
              for textField in searchController.searchBar.subviews.first.subviews where   textField is UITextField {
              textField.subviews.first.backgroundColor = .white
              textField.subviews.first.layer.cornerRadius = 10
              textField.subviews.first.layer.masksToBounds = true
                }
              }
              

              【讨论】:

                【解决方案10】:

                在 iOS 12 及以下版本中,需要覆盖文本字段内的图像,该图像给出了我们想要更改的背景颜色。 您可以在 imageview 之后的索引 1 处添加自定义视图以实现您想要的。

                if #available(iOS 13.0, *)
                    {
                        searchBar.searchTextField.textColor       = .black
                        searchBar.searchTextField.backgroundColor = .red
                    }
                    else if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
                    {
                        textFieldInsideSearchBar.textColor = .black
                        let backgroundView = UIView(frame: textFieldInsideSearchBar.bounds)
                        backgroundView.backgroundColor = .red
                        backgroundView.layer.cornerRadius = 10
                        backgroundView.clipsToBounds = true
                        textFieldInsideSearchBar.insertSubview(backgroundView, at: 1)
                    }
                

                【讨论】:

                  【解决方案11】:

                  你有没有尝试过类似的东西

                  searchController.searchBar.backgroundColor = UIColor.blue
                  

                  【讨论】:

                  • 好的!也许您可以尝试使用 searchBar 内的子视图,如果您找到一个 UITextField 的子视图,请更改其背景颜色
                  猜你喜欢
                  • 1970-01-01
                  • 2015-06-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-12-25
                  • 1970-01-01
                  • 2013-05-20
                  相关资源
                  最近更新 更多