If you want to set text color for UISearchBar in storyboard (without code), it is easy to do as well (in identity inspector). Here is a red text for search bar.
You can do this by accessing the UITextField inside the searchBar,
then you can change its background color, text color, and all other UITextField properties
add the following extension to access the 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
}
}
Here is a Xamarin.iOS C# version of the "find the UITextField" approach. It will not crash if the UITextField disappears in future iOS view hierarchy.
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;
}
}
}
Since Xcode 11 and iOS 13 it has become possible to access the text field directly:
searchBar.searchTextField
You could write some code to always make it accessible like this.
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
}
}
You could also make it not optional with fatal errors, this code is tested since iOS 7 up to iOS 13GM. But i would just go for the optional version.
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")
}
}
I tried a few of the solutions written above but they didn't work (anymore, I guess).
If you only want to handle iOS 13:
mySearchBar.searchTextField.textColor = .red
But if you want to handle older iOS too, Here is the way I did :
Create a custom UISearchBar class, called SearchBar : UISearchBar, UISearchBarDelegate
This SearchBar will have the UISearchBarDelegate methods I wanna handle and its delegate set.
With iOS13 now, you can access the UITextField thanks to UISearchBar.searchTextField, which is of type UISearchTextField, which inherits from UITextField.
Since I know my hierarchy, I know my textField won't be nill for older versions so in both case, I get a textfield I can easily customize, working on every version, from 9 to 13 today.
[Update]
I observed, the app crashes on older versions (< iOS 13), But compiler never complained about the version check, someone please explain why this happened.