Jak mogę zmienić kolor tekstu wyszukiwania w UISearchBar?

88

Jak mogę zmienić kolor tekstu UISearchBar?

MrTourkos
źródło

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
chrześcijanin
źródło
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

przerwać
źródło
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]
chronikum
źródło
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
Boczek
źródło
@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
    }
}
Adam Waite
źródło
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.

juanjo
źródło
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
Tal Zion
źródło
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")
    }
}
Saren Inden
źródło
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.

nieskończona pętla
źródł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
    }
}
Omar Albeik
źródło
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!).

Bryan ORTIZ
źródło
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 }
    }
}
David Steppenbeck
źródło
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
Nrv
źródło
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;
        }
    }
}
t9mike
źródło
1

Swift 5.2 i iOS 13.3.1: -

To działa dobrze.

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

Dinesh Kumar
źródło
0

W mojej sytuacji rozwiązaniem jest

id appearance = [UITextField appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class, BCRSidebarController.class]];
[appearance setTextColor:[UIColor.whiteColor colorWithAlphaComponent:0.56]];
poGUIst
źródło
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
Argus
źródło
0

Swift 5:

searchBar[keyPath: \.searchTextField].textColor = UIColor(...)

ramzesenok
źródło
0

W Swift 5 możesz zrobić coś takiego jak poniżej:

yourSearchBar.searchTextField.textColor = .yourColor
nieznany z nazwiska
źródło
0

To zadziałało dla mnie.

    if #available(iOS 13.0, *) {
     searchBar.searchTextField.textColor = .white
    }
Mili
źródło
-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)
blyscuit
źródło