Невозможно изменить цвет фона панели поиска

У меня есть панель поиска:

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 и что я сделал неправильно?

Ответ 1

Если вы хотите изменить его в своем 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 или новее, тогда должно быть использование outerWhenContainedInInstancesOfClasses, например

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

Ответ 2

Вы добавляете приведенный ниже код в ViewDidLoad и меняете цвет фона поля поля RED,

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

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

}

Красный цвет TextField в SearchBar.

enter image description here

Ответ 3

Для 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
        }
     }
}

Ответ 4

Способ сделать это только с помощью API Apple - создать изображение и использовать setSearchFieldBackgroundImage:

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

Он даже будет правильно анимировать углы, если вы создадите скругленный прямоугольник и динамически отобразите и скроете кнопки.

Пример использования этого изображения: enter image description here

enter image description here

Ответ 5

Как и @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...
}

Когда searchBar находится в tableHeaderView вышеуказанный код может быть вызван в viewWillAppear, но если он находится в navigationItem viewWillAppear на iOS 11 и выше, он должен быть вызван в viewDidAppear.

Ответ 6

Так же, как этот

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

Ответ 7

Я делаю это с помощью этого метода (Swift 3+):

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

Ответ 8

FWIW Я решаю эту проблему, создав вычисленную переменную с именем textField.

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

Ответ 9

Очень общий ответ на этот вопрос в Интернете - это решение, описанное выше:

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

Но это не сработало для меня, используя XCode 7 и iOS 9, и я заметил, что по всему миру многие другие сообщили, что они тоже не работают для них. Я обнаружил, что подвью UITextField не создано (или, по крайней мере, оно не добавлено как подвью) до тех пор, пока не будет указано, и один из способов, на который он может ссылаться, - это поле заполнителя, например, можно было бы добавить эту строку перед поиском subviews для класса UITextField:

searchBar.placeholder = searchBar.placeholder

Ответ 10

Здесь решение:

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, *) {}

Ответ 11

Я экспериментировал со свойствами 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

Ответ 12

Установите любой цвет, который вы хотите. 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!
  }
}

Ответ 13

Расширение UISearchBar с использованием Swift 4, основанное на ответе с наибольшим количеством голосов

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

Ответ 14

Я сделал одно расширение UISearchBar & категория для настройки текста в строке поиска.

Совместимо с iOS 9 до iOS 13.

Свифт 4+

import UIKit

extension UISearchBar {
    var dtXcode: Int {
        if let dtXcodeString = Bundle.main.infoDictionary?["DTXcode"] as? String {
            if let dtXcodeInteger = Int(dtXcodeString) {
                return dtXcodeInteger
            }
        }
        return Int()
    }

    // 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, *), dtXcode >= 1100 else { return legacySearchField }
        return self.searchTextField
    }

    var legacySearchField: UITextField {
        guard let textField = self.subviews.first?.subviews.last as? UITextField else { return UITextField() }
        return textField
    }
}

Пример использования:

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

Objective-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
        return (UITextField *)[self valueForKey:@"searchField"];
#endif
    } else {
        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
}

Более подробно, пожалуйста, обратитесь Гист

Ответ 15

Просто попробуйте свой код, как показано ниже на детской площадке. Если все же это не сработает, добавьте еще один код в свой вопрос...

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

Ответ 16

Я просто пришел к тому, чтобы поделиться ТОЛЬКО способом изменения цвета фона для текстового поля searchbar, потому что я еще не видел его в любом ответе, и ни одно из других предложений здесь или на других сайтах не работало для меня.

  • Получите textField из панели поиска, как и ответ от @Steve... все работает здесь, пока вы получаете textField. Это не моя проблема, дело в том, что она не меняла цвета, которые я установил здесь, это не работало 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 } }

  • Создайте новый слой с размером let layer = CALayer() layer.backgroundColor = UIColor.white.withAlphaComponent(0.5).cgColor//Set your color here layer.frame = navigationBar.frame navigationBar 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) по текстовому 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 с любым цветом, который вы хотите.

Ответ 17

решение, предоставленное @Ángel Téllez, тоже помогло мне! Спасибо, Ангел! Не уверен, что он будет работать и для IOS 10, но он работает для 11. Кроме того, если один незначительный сбой пользовательского интерфейса, где для вспышки (под второй), есть белая строка, которая появляется между заголовком навигации и контроллером панели поиска. Не знаю, почему это происходит, но рад, что это работает!

Ответ 18

Здесь решение

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