Reputation: 549
I feel like I’m taking crazy pills. I want to change the color of the textfield within a UISearchBar, which is hosted in a UINavigationBar. The problem I’m having is that the UISearchBar gets the color of the UINavigationBar but the TextField doesn’t change color. I’ve tried several solutions here, but none of them seem to solve the issue. Any ideas how to change the TextField’s color?
I know there are other questions out there similar to this but I’ve tried every possible solution I’ve come across and haven’t found one that solves my issue.
Current Code:
let sc = UISearchController(searchResultsController: nil)
sc.delegate = self
let scb = sc.searchBar
scb.tintColor = UIColor.green
scb.barTintColor = UIColor.yellow
if let textfield = scb.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.blue
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.red
// Rounded corner
backgroundview.layer.cornerRadius = 5;
backgroundview.clipsToBounds = true;
}
}
navigationController?.navigationBar.barTintColor = UIColor.blue
navigationItem.searchController = sc
navigationItem.hidesSearchBarWhenScrolling = false
I’ve created a sample project to show it in action. Any help or guidance would be greatly appreciated!
Upvotes: 3
Views: 311
Reputation: 844
Maybe the best solution is for creating an extension for UISearchBar if you want to use these settings in more controllers. Here are some example.
extension UISearchBar {
private func getViewElement<T>(type: T.Type) -> T? {
let svs = subviews.flatMap { $0.subviews }
guard let element = (svs.filter { $0 is T }).first as? T else { return nil }
return element
}
func getSearchBarTextField() -> UITextField? {
return getViewElement(type: UITextField.self)
}
func setTextColor(color: UIColor) {
if let textField = getSearchBarTextField() {
textField.textColor = color
}
}
func setTextFieldColor(color: UIColor) {
if let textField = getViewElement(type: UITextField.self) {
switch searchBarStyle {
case .minimal:
textField.layer.backgroundColor = color.cgColor
textField.layer.cornerRadius = 6
case .prominent, .default:
textField.backgroundColor = color
@unknown default:
print("something")
}
}
}
func setPlaceholderTextColor(color: UIColor) {
if let textField = getSearchBarTextField() {
textField.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes: [NSAttributedString.Key.foregroundColor: color])
}
}
func setTextFieldClearButtonColor(color: UIColor) {
if let textField = getSearchBarTextField() {
let button = textField.value(forKey: "clearButton") as! UIButton
if let image = button.imageView?.image {
button.setImage(image.transform(withNewColor: color), for: .normal)
}
}
}
func setSearchImageColor(color: UIColor) {
if let imageView = getSearchBarTextField()?.leftView as? UIImageView {
imageView.image = imageView.image?.transform(withNewColor: color)
}
}
}
Update:
Change navigationItem.searchController = sc
to navigationItem.titleView = sc.searchBar
.
Upvotes: 1