Как я могу изменить цвет текста поиска 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.