Changing Search Bar placeholder text colour in iOS 13

Viewed 4315

UI Search Bar

I'm trying to set colour for placeholder text inside UISearchbar. Right now I've following code. It doesn't set white colour to placeholder text on iOS 13. It works on iOS 12. It seems something is either broken or support has been removed in iOS 13?

I've searched a lot and tried few workarounds but doesn't work. I've also tried to set attributed text colour for textfield but that also doesn't change colour.

Is there a working solution for this?

class CustomSearchBar: UISearchBar {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.sizeToFit()

        // Search text colour change
        let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
        textFieldInsideSearchBar?.textColor = UIColor.white

        // Search Placeholder text colour change
        let placeHolderText = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
        placeHolderText?.textColor = UIColor.white // doesn't work
    }
}
5 Answers

viewDidLoad is too early

Put the code in viewDidAppear, viewDidLoad is too early. Then your placeholder should change to white

searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Enter Search Here", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white])

In viewDidAppear

if iOS is higher than 13.0, use searchBar.searchTextField.attributedPlaceholder.

if iOS is lower than 13.0, use searchBar.value(forKey: "searchField") to access searchTextField

var searchBar = UISearchBar()
override func viewDidAppear(_ animated: Bool) {
   super.viewDidAppear(animated)
   if #available(iOS 13.0, *) {
       searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Enter Search Here", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white])
   } else {
       if let searchField = searchBar.value(forKey: "searchField") as? UITextField {
           searchField.attributedPlaceholder = NSAttributedString(string: "Enter Search Here", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white2])
       }
   }
}

Try this:

var searchBar: UISearchBar!
        if let textfield = searchBar.value(forKey: "searchField") as? UITextField {
            textfield.attributedPlaceholder = NSAttributedString(string: textfield.placeholder ?? "", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white])
        }

Please add this extension and try this !

 extension UISearchBar{
        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)
            placeholderLabel.removeFromSuperview() // To remove existing label. Otherwise it will overwrite it if called multiple times.
            setValue(label, forKey: "placeholderLabel")
        }
    }

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) }
}

Usage

yourSearchBarObject.setPlaceholder(textColor: .red)

You need to style everything in viewDidAppear

Related