Jak mogę zmienić kolor tekstu wyszukiwania w UISearchBar?


Odpowiedzi:


108

Musisz uzyskać dostęp do UITextFieldwnętrza UISearchBar. Możesz to zrobić za pomocąvalueForKey("searchField")

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

textFieldInsideSearchBar?.textColor = yourcolor

Aktualizacja Swift 3

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

textFieldInsideSearchBar?.textColor = yourcolor

1
Zmieniłem odpowiedź. Dostęp do pola można uzyskać za pomocą wartości klucz-wartość („searchField”)
Christian

7
Nie jest to prywatny interfejs API, ale jest bardzo delikatny i może się zepsuć przy dowolnej aktualizacji iOS. Nigdy nie powinieneś używać takich rzeczy w kodzie produkcyjnym
Lope

2
@Christian - nie ma znaczenia, kiedy opublikowano oryginalną odpowiedź, nadal opiera się na prywatnym API. Gdyby był publiczny, nie musiałbyś uzyskiwać dostępu searchFieldprzez KVC.
Greg Brown

1
Głosuj przeciw. Zobacz odpowiedź @ juanjo i mój komentarz, aby uzyskać znacznie solidniejsze podejście zatwierdzone przez Apple i znacznie mniej podatne na awarie.
RobP

1
Nie używaj tej odpowiedzi, uzyskujesz dostęp do prywatnych interfejsów API i może to spowodować odrzucenie Twojej aplikacji.
aryaxt

64

Jeśli chcesz ustawić kolor tekstu dla UISearchBar w scenorysie (bez kodu), również jest to łatwe (w inspektorze tożsamości). Oto czerwony tekst paska wyszukiwania.

wprowadź opis obrazu tutaj


2
Lepiej jest mieć mniej kodu dla elementów widoku. Dzięki.
NRR

Idealne rozwiązanie!
Mona

49

Praca w Swift 4 dla mnie:

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]

Pracuje dla mnie.
Surjeet Rajput

i zmienia kolor dla każdego paska wyszukiwania w module?
Zaporozhchenko Oleksandr

48

Jeśli chcesz, aby był czytelny na ciemnym tle, możesz zmienić styl paska. Poniższe powoduje, że tekst i przyciski na pasku wyszukiwania są białe:

searchController.searchBar.barStyle = .black

@Bacon, to też pomogło! Dzięki
Goppinath

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

Jak ty rozwiązanie. Dzięki.
Bagusflyer

Możesz także dodać „searchField.backgroundColor”, aby kontrolować kolor tła pola tekstowego niezależnie od odcienia paska.
Sherwin Zadeh

13

Działa to dla mnie na iOS 11, Xcode 9:

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

Piszę to w, AppDelegateale myślę, że działa, jeśli umieścisz to również w innym miejscu.


3
Jest to znacznie solidniejsze podejście niż nonsens klucz-wartość w zaakceptowanej odpowiedzi i innych odpowiedziach. Jednak Apple w swojej mądrości wycofał używane tutaj API i oferuje nową wersję dla iOS 9.0 i nowszych, na przykład: [[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];To jest oczywiście Objective-C, z oczywistym tłumaczeniem na Swift przy użyciuappearance(whenContainedInInstancesOf:)
RobP

2
Wydaje się, że nie działa dla mnie w Xcode 10, iOS 12, na rzeczywistym urządzeniu.
Oded

10

Myślę, że najwygodniejszy sposób to ustawienie textColornieruchomości w 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
               }
           }
       }
   }

Stosowanie

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

Użyłbyś go jako:

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

nie działa dla mnie. kiedy ustawiasz właściwość textcolor?
Kingalione

1
@Kingalione możesz ustawić to w 'viewDidLoad ()'
Tal Zion

Tak, chciałem zmienić kolor tekstu w folderze. Teraz znalazłem rozwiązania. W każdym razie dzięki
Kingalione

10

Od Xcode 11 i iOS 13 możliwy jest bezpośredni dostęp do pola tekstowego:

searchBar.searchTextField

Możesz napisać jakiś kod, aby zawsze był dostępny w ten sposób.

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

Możesz również uczynić to nie opcjonalnym z błędami krytycznymi, ten kod jest testowany od iOS 7 do iOS 13GM. Ale wybrałbym tylko wersję opcjonalną.

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

Wreszcie! Mamy bezpośredni dostęp do pola tekstowego. Dzięki, Saren.
Mark Moeykens

4

Spróbuj tego,

searchBar.searchTextField.textColor = .white

Używam tego z aplikacją ukierunkowaną na iOS 11 i nowsze.

[Aktualizacja] Zauważyłem, że aplikacja wywala się na starszych wersjach (<iOS 13), ale kompilator nigdy nie narzekał na sprawdzenie wersji, ktoś proszę wyjaśnić, dlaczego tak się stało.


3

Możesz to zrobić, uzyskując dostęp do UITextField wewnątrz searchBar, a następnie możesz zmienić jego kolor tła, kolor tekstu i wszystkie inne właściwości UITextField

Dodaj następujące rozszerzenie, aby uzyskać dostęp do 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

Wypróbowałem kilka z opisanych powyżej rozwiązań, ale nie działały (chyba już).

Jeśli chcesz obsługiwać tylko iOS 13:

mySearchBar.searchTextField.textColor = .red

Ale jeśli chcesz obsługiwać również starsze iOS, oto sposób, w jaki zrobiłem:

Utwórz UISearchBarklasę niestandardową o nazwie SearchBar : UISearchBar, UISearchBarDelegate This SearchBarwill be mieć UISearchBarDelegatemetody, które chcę obsługiwać, i jej delegatezestaw.

I dodaję do klasy:

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

Krótkie wyjaśnienie:

Dzięki iOS13 możesz teraz uzyskać dostęp do UITextFieldpodziękowania UISearchBar.searchTextField, który jest typem UISearchTextField, który dziedziczy z UITextField.

Ponieważ znam swoją hierarchię, wiem, textFieldże nie będęnill dla starszych wersji, więc w obu przypadkach otrzymuję pole tekstowe, które mogę łatwo dostosować, pracując nad każdą wersją, od 9 do 13 dzisiaj.

Oto pełny kod potrzebny do działania:


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

}

Możesz również włączyć niektóre opcje dostosowywania SearchBar, dodając to na:

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

Następnie ustawiasz go na XIB / Storyboard i traktujesz to tak, jakby to było proste UISearchBar(jeśli nie zapomniałeś o delegatach!).


2

(To rozwiązanie przetestowane tylko dla Xcode 10 i iOS 12.) Dodaj rozszerzenie, aby uzyskać dostęp do pola tekstowego paska wyszukiwania:

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

Następnie użyj tej właściwości, aby ustawić kolor tekstu pola tekstowego na pasku wyszukiwania:

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

// EDYTOWAĆ

Powyższy kod nie działa na iOS 13. Lepszym sposobem na rozwiązanie tego problemu jest użycie:

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

dla iOS 13 return subviews.first? .subviews.last? .subviews.compactMap {$ 0 as? UITextField} .last
Taras

2

// Spróbuj tego gościa

yourSearchbar.searchTextField.textColor = .white

1

Oto wersja C # Xamarin.iOS podejścia „znajdź UITextField”. Nie nastąpi awaria, jeśli UITextField zniknie z przyszłej hierarchii widoków 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 i iOS 13.3.1: -

To działa dobrze.

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


0

W mojej sytuacji rozwiązaniem jest

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

To zadziałało dla mnie.

    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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.