Як я можу змінити колір тексту пошуку 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.
Greg Brown

1
Проголосувати проти. Дивіться відповідь @ juanjo та мій коментар щодо набагато більш надійного підходу, схваленого Apple, і набагато рідшого зриву.
RobP

1
Не використовуйте цю відповідь, ви отримуєте доступ до приватних API, і ваш додаток може бути відхилено.
aryaxt

63

Якщо ви хочете встановити колір тексту для UISearchBar у розкадруванні (без коду), це також легко зробити (в інспекторі ідентифікації). Ось червоний текст для рядка пошуку.

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


2
Краще мати менше коду для елементів перегляду. Дякую.
NRR

Ідеальне рішення!
Мона

49

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

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

Свіфт 4.2, IOS 12:

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

Працює на мене.
Surjeet Rajput

і це змінює колір для кожної панелі пошуку в модулі?
Запорожченко Олександр

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, на реальному пристрої.
Оді

10

Я вважаю, що найзручніший спосіб встановити textColorвластивість UISearchBar.

Свіфт 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

Свіфт 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?
Кінгаліоне

1
@Kingalione, ти можеш встановити це в 'viewDidLoad ()'
Tal Zion,

Так, я хотів змінити колір тексту плахольдера. Тепер я знайшов рішення. Все одно
дякую

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 всередині панелі пошуку, потім ви можете змінити його колір тла, колір тексту та всі інші властивості UITextField

додайте наступне розширення для доступу до textField

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 як? UITextField}. Last
Тарас

2

// Спробуй цього хлопця

yourSearchbar.searchTextField.textColor = .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;
        }
    }
}

1

Swift 5.2 та iOS 13.3.1: -

Це чудово працює.

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


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

Свіфт 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.