How to change UISearchBar Placeholder and image tint color? How to change UISearchBar Placeholder and image tint color? xcode xcode

How to change UISearchBar Placeholder and image tint color?


Details

  • Xcode Version 11.0 (11A420a), iOS 13, swift 5

Solution

import UIKitextension UISearchBar {    func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }    func set(textColor: UIColor) { if let textField = getTextField() { textField.textColor = textColor } }    func setPlaceholder(textColor: UIColor) { getTextField()?.setPlaceholder(textColor: textColor) }    func setClearButton(color: UIColor) { getTextField()?.setClearButton(color: color) }    func setTextField(color: UIColor) {        guard let textField = getTextField() else { return }        switch searchBarStyle {        case .minimal:            textField.layer.backgroundColor = color.cgColor            textField.layer.cornerRadius = 6        case .prominent, .default: textField.backgroundColor = color        @unknown default: break        }    }    func setSearchImage(color: UIColor) {        guard let imageView = getTextField()?.leftView as? UIImageView else { return }        imageView.tintColor = color        imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)    }}private extension UITextField {    private class Label: UILabel {        private var _textColor = UIColor.lightGray        override var textColor: UIColor! {            set { super.textColor = _textColor }            get { return _textColor }        }        init(label: UILabel, textColor: UIColor = .lightGray) {            _textColor = textColor            super.init(frame: label.frame)            self.text = label.text            self.font = label.font        }        required init?(coder: NSCoder) { super.init(coder: coder) }    }    private class ClearButtonImage {        static private var _image: UIImage?        static private var semaphore = DispatchSemaphore(value: 1)        static func getImage(closure: @escaping (UIImage?)->()) {            DispatchQueue.global(qos: .userInteractive).async {                semaphore.wait()                DispatchQueue.main.async {                    if let image = _image { closure(image); semaphore.signal(); return }                    guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return }                    let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44))                    window.rootViewController?.view.addSubview(searchBar)                    searchBar.text = "txt"                    searchBar.layoutIfNeeded()                    _image = searchBar.getTextField()?.getClearButton()?.image(for: .normal)                    closure(_image)                    searchBar.removeFromSuperview()                    semaphore.signal()                }            }        }    }    func setClearButton(color: UIColor) {        ClearButtonImage.getImage { [weak self] image in            guard   let image = image,                let button = self?.getClearButton() else { return }            button.imageView?.tintColor = color            button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)        }    }    var placeholderLabel: UILabel? { return value(forKey: "placeholderLabel") as? UILabel }    func setPlaceholder(textColor: UIColor) {        guard let placeholderLabel = placeholderLabel else { return }        let label = Label(label: placeholderLabel, textColor: textColor)        setValue(label, forKey: "placeholderLabel")    }    func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }}

Full Sample

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()        let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))        searchBar.searchBarStyle = .default        view.addSubview(searchBar)        searchBar.placeholder = "placeholder"        searchBar.set(textColor: .brown)        searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))        searchBar.setPlaceholder(textColor: .white)        searchBar.setSearchImage(color: .white)        searchBar.setClearButton(color: .red)    }}

Result

enter image description hereenter image description here


If you have a custom image you could use, you can set the image and change the placeholder text color using something similar to the following:

[searchBar setImage:[UIImage imageNamed:@"SearchWhite"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];UITextField *searchTextField = [searchBar valueForKey:@"_searchField"];    if ([searchTextField respondsToSelector:@selector(setAttributedPlaceholder:)]) {    UIColor *color = [UIColor purpleColor];    [searchTextField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"Search" attributes:@{NSForegroundColorAttributeName: color}]];}

In that example I used purpleColor, instead you can use the + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha method to create your custom dark green color.

EDIT: I just realized you were writing it in swift... duh. Quickly typed this out so I didn't leave the answer in just Obj-C.

    searchBar.setImage(UIImage(named: "SearchWhite"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal);    var searchTextField: UITextField? = searchBar.valueForKey("searchField") as? UITextField    if searchTextField!.respondsToSelector(Selector("attributedPlaceholder")) {        var color = UIColor.purpleColor()        let attributeDict = [NSForegroundColorAttributeName: UIColor.purpleColor()]        searchTextField!.attributedPlaceholder = NSAttributedString(string: "search", attributes: attributeDict)    }

Swift 3.0

    var searchTextField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField    if searchTextField!.responds(to: #selector(getter: UITextField.attributedPlaceholder)) {        let attributeDict = [NSForegroundColorAttributeName: UIColor.white]        searchTextField!.attributedPlaceholder = NSAttributedString(string: "Search", attributes: attributeDict)    }


Swift 3: If you want to change the placeholder, clearbutton and magnifier glass

    let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField    textFieldInsideSearchBar?.textColor = UIColor.white    let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel    textFieldInsideSearchBarLabel?.textColor = UIColor.white    let clearButton = textFieldInsideSearchBar?.value(forKey: "clearButton") as! UIButton    clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal)    clearButton.tintColor = UIColor.white    let glassIconView = textFieldInsideSearchBar?.leftView as? UIImageView    glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate)    glassIconView?.tintColor = UIColor.white