Jak mogę zmienić kolor tekstu UISearchBar
?
Odpowiedzi:
Musisz uzyskać dostęp do UITextField
wnę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
searchField
przez KVC.
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]
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
}
}
Działa to dla mnie na iOS 11, Xcode 9:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.blue
Piszę to w, AppDelegate
ale myślę, że działa, jeśli umieścisz to również w innym miejscu.
[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTextColor:[UIColor blueColor]];
To jest oczywiście Objective-C, z oczywistym tłumaczeniem na Swift przy użyciuappearance(whenContainedInInstancesOf:)
Myślę, że najwygodniejszy sposób to ustawienie textColor
nieruchomoś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
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")
}
}
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.
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
}
}
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 UISearchBar
klasę niestandardową o nazwie SearchBar : UISearchBar, UISearchBarDelegate
This SearchBar
will be mieć UISearchBarDelegate
metody, które chcę obsługiwać, i jej delegate
zestaw.
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 UITextField
podzię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!).
(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 }
}
}
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;
}
}
}
Swift 5.2 i iOS 13.3.1: -
To działa dobrze.
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
Swift 5:
searchBar[keyPath: \.searchTextField].textColor = UIColor(...)
W Swift 5 możesz zrobić coś takiego jak poniżej:
yourSearchBar.searchTextField.textColor = .yourColor