Как я могу изменить цвет текста поиска UISearchBar?


Ответы:


108

Вы должны получить доступ к UITextFieldвнутренней части UISearchBar. Вы можете сделать это, используяvalueForKey("searchField")

var textFieldInsideSearchBar = yourSearchbar.valueForKey("searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

Обновление Swift 3

let textFieldInsideSearchBar = yourSearchbar.value(forKey: "searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

1
Я отредактировал свой ответ. Вы можете получить доступ к полю с помощью valueforkey ("searchField")
Кристиан,

7
Это не частный API, но он очень хрупкий и может сломаться при любом обновлении iOS. Вы никогда не должны использовать подобные вещи в производственном коде
Лопе

2
@Christian - не имеет значения, когда был опубликован исходный ответ, он по-прежнему полагается на частный API. Если бы он был общедоступным, вам не нужно было бы получать доступ searchFieldчерез KVC.
Грег Браун

1
Голосовать против. См. Ответ @ juanjo и мой комментарий, чтобы узнать о гораздо более надежном подходе, одобренном Apple и с гораздо меньшей вероятностью сломаться.
RobP

1
Не используйте этот ответ, вы получаете доступ к частным API, и ваше приложение может быть отклонено.
aryaxt

64

Если вы хотите установить цвет текста для UISearchBar в раскадровке (без кода), это тоже легко сделать (в инспекторе идентичности). Вот красный текст для панели поиска.

введите описание изображения здесь


2
Лучше иметь меньше кода для элементов представления. Спасибо.
NRR

Отличное решение!
Мона

49

Работаю в Swift 4 для меня:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.white]

Swift 4.2, IOS 12:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

Работаю на меня.
Сурджит Раджпут,

и он меняет цвет для каждой панели поиска в модуле?
Запорожченко Александр

48

Если вам нужно только сделать его читабельным на темном фоне, вы можете изменить barStyle. Следующее делает текст и кнопки на панели поиска белыми:

searchController.searchBar.barStyle = .black

@Bacon, Тоже помогло! Спасибо
Гоппинатх

32
public extension UISearchBar {

    public func setTextColor(color: UIColor) {
        let svs = subviews.flatMap { $0.subviews }
        guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return }
        tf.textColor = color
    }
}

Нравится вам решение. Спасибо.
Bagusflyer

Вы также можете добавить searchField.backgroundColor для управления цветом фона текстового поля отдельно от оттенка полосы.
Шервин Заде

13

Это работает для меня на iOS 11, Xcode 9:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.blue

Я пишу это в, AppDelegateно, думаю, он работает, если вы положите его в другое место.


3
Это гораздо более надежный подход, чем бессмыслица "ключ-значение" в принятом ответе и других ответах. Однако Apple в своей мудрости отказалась от API, который вы здесь используете, и предлагает новую версию для iOS 9.0 и выше, например: [[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];Это, конечно, Objective-C с очевидным переводом на Swift с использованиемappearance(whenContainedInInstancesOf:)
RobP

2
Похоже, у меня не работает Xcode 10, iOS 12 на реальном устройстве.
Oded

10

Я считаю, что самый удобный способ - установить textColorсвойство UISearchBar.

Swift 3.0

    extension UISearchBar {

       var textColor:UIColor? {
           get {
               if let textField = self.value(forKey: "searchField") as? 
   UITextField  {
                   return textField.textColor
               } else {
                   return nil
               }
           }

           set (newValue) {
               if let textField = self.value(forKey: "searchField") as? 
   UITextField  {
                   textField.textColor = newValue
               }
           }
       }
   }

Применение

searchBar.textColor = UIColor.blue // Your color

Swift 2.3

extension UISearchBar {

 var textColor:UIColor? {
     get {
         if let textField = self.valueForKey("searchField") as? UITextField  {
             return textField.textColor
         } else {
             return nil
         }
     }

     set (newValue) {
         if let textField = self.valueForKey("searchField") as? UITextField  {
             textField.textColor = newValue
         }
     }
 }
} 

Вы бы использовали его как:

searchBar.textColor = UIColor.blueColor() // Your color

у меня не работает. когда вы устанавливаете свойство textcolor?
Kingalione

1
@Kingalione, вы можете установить это в 'viewDidLoad ()'
Tal Zion

Да, я хотел изменить цвет текста на плахолдере. Теперь я нашел решение. В любом случае спасибо
Kingalione

10

Начиная с Xcode 11 и iOS 13 появилась возможность напрямую обращаться к текстовому полю:

searchBar.searchTextField

Вы можете написать код, чтобы он всегда был таким доступным.

extension UISearchBar {
    public var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return searchTextField
        } 

        guard let firstSubview = subviews.first else {
            assertionFailure("Could not find text field")
            return nil
        }

        for view in firstSubview.subviews {
            if let textView = view as? UITextField {
                return textView
            }
        }

        assertionFailure("Could not find text field")

        return nil
    }
}

Вы также можете сделать это необязательным с фатальными ошибками, этот код протестирован с iOS 7 до iOS 13GM. Но я бы просто выбрал дополнительную версию.

extension UISearchBar {
    public var textField: UITextField {
        if #available(iOS 13.0, *) {
            return searchTextField
        }

        guard let firstSubview = subviews.first else {
            fatalError("Could not find text field")
        }

        for view in firstSubview.subviews {
            if let textView = view as? UITextField {
                return textView
            }
        }

       fatalError("Could not find text field")
    }
}

В заключение! Мы можем получить доступ к текстовому полю напрямую. Спасибо, Сарен.
Марк Мойкенс

4

Попробуй это,

searchBar.searchTextField.textColor = .white

Я использую это с приложением, ориентированным на iOS 11 и новее.

[Обновление] Я заметил, что приложение вылетает в старых версиях (<iOS 13), но компилятор никогда не жаловался на проверку версии, кто-нибудь, пожалуйста, объясните, почему это произошло.


3

Вы можете сделать это, обратившись к UITextField внутри searchBar, затем вы можете изменить его цвет фона, цвет текста и все другие свойства UITextField.

добавьте следующее расширение для доступа к текстовому полю

extension UISearchBar {
    /// Return text field inside a search bar
    var textField: UITextField? {
        let subViews = subviews.flatMap { $0.subviews }
        guard let textField = (subViews.filter { $0 is UITextField }).first as? UITextField else { return nil
        }
        return textField
    }
}

3

Я попробовал несколько решений, написанных выше, но они не работали (полагаю, больше).

Если вы хотите работать только с iOS 13:

mySearchBar.searchTextField.textColor = .red

Но если вы хотите работать и со старой iOS, вот как я поступил:

Создайте собственный UISearchBarкласс с именем SearchBar : UISearchBar, UISearchBarDelegate This SearchBarбудет иметь UISearchBarDelegateметоды, которые я хочу обработать, и их delegateнабор.

И добавляю в класс:

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        }
        return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
    }

Краткое объяснение:

Теперь с iOS13 вы можете получить доступ к UITextFieldблагодарности UISearchBar.searchTextField, которая имеет тип UISearchTextField, наследуемый от UITextField.

Поскольку я знаю свою иерархию, я знаю, что моей textFieldне будетnill использовать старые версии, поэтому в обоих случаях я получаю текстовое поле, которое я могу легко настроить, работая над каждой версией, с 9 по 13 сегодня.

Вот полный код, необходимый для работы:


class SearchBar: UISearchBar, UISearchBarDelegate {

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return self.searchTextField
        }
        return subviews.first?.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField
    }


    override func awakeFromNib() {
        super.awakeFromNib()

        delegate = self

        if let textField = textField {
            textField.textColor = .red
            textField.clearButtonMode = .whileEditing
            textField.returnKeyType = .search
        }
    }

}

Вы также можете настроить некоторые параметры SearchBar, добавив это в:

        let searchBar = UISearchBar.appearance(whenContainedInInstancesOf: [SearchBar.self])
        searchBar.backgroundImage = UIImage()
        searchBar.isTranslucent = false
        searchBar.returnKeyType = .search

Затем вы устанавливаете его в XIB / Storyboard и обрабатываете его, как если бы он был простым UISearchBar(если вы не забыли делегатов!).


2

(Это решение протестировано только для Xcode 10 и iOS 12.) Добавьте расширение для доступа к текстовому полю панели поиска:

extension UISearchBar {
    var textField: UITextField? {
        return subviews.first?.subviews.compactMap { $0 as? UITextField }.first
    }
}

Затем используйте это свойство, чтобы установить цвет текста текстового поля в строке поиска:

let searchBar = UISearchBar()
searchBar.textField?.textColor = UIColor.white // or whichever color you want

// РЕДАКТИРОВАТЬ

Приведенный выше код не работает для iOS 13. Лучший способ справиться с этим - использовать:

extension UISearchBar {
    var textField: UITextField? {
        return self.subviews(ofType: UITextField.self).first
    }
}

extension UIView {
    var recursiveSubviews: [UIView] {
        return self.subviews + self.subviews.flatMap { $0.recursiveSubviews }
    }

    func subviews<T: UIView>(ofType: T.Type) -> [T] {
        return self.recursiveSubviews.compactMap { $0 as? T }
    }
}

для iOS 13 вернуть subviews.first? .subviews.last? .subviews.compactMap {$ 0 as? UITextField} .last
Тарас

2

// Попробуйте этого парня

yourSearchbar.searchTextField.textColor = .white

2

Swift 5.2 и iOS 13.3.1: -

Работает нормально.

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]


1

Вот версия Xamarin.iOS C # подхода «найти UITextField». Он не выйдет из строя, если UITextField исчезнет в будущей иерархии представлений iOS.

var tf = searchBar.AllSubViews().FirstOrDefault(v => v is UITextField);
if (tf != null) 
    (tf as UITextField).TextColor = UIColor.White;

public static IEnumerable<UIView> AllSubViews(this UIView view)
{
    foreach (var v in view.Subviews)
    {
        yield return v;
        foreach (var sv in v.AllSubViews())
        {
            yield return sv;
        }
    }
}

0

В моей ситуации решение

id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];

0

Obj-C

UITextField *textField = [self.yourSearchbar valueForKey:@"_searchField"];
textField.textColor = [UIColor redColor];

Swift 4.x

let textField = yourSearchbar.value(forKey: "searchField") as? UITextField
textField?.textColor = UIColor.red


0

В Swift 5 вы можете сделать что-то вроде следующего:

yourSearchBar.searchTextField.textColor = .yourColor

0

Это сработало для меня.

    if #available(iOS 13.0, *) {
     searchBar.searchTextField.textColor = .white
    }

-1

Swift 5 Xcode 11.4 iOS 13.4

    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = .white
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = .systemFont(ofSize: 13)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.