7

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
    }
}
Raymond
  • 1,108
  • 13
  • 32
  • 1
    Did you find a solution? I found same code in the answer everywhere I searched. It didn't work for placeholder textColor, instead it changes the searchBar text color. – iUser Mar 04 '20 at 23:14
  • Weird that still none of the solutions work for me. Every attribute can be set except for the text colour (background, shadow etc.) – Tum Oct 22 '20 at 16:02

5 Answers5

7

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])
Community
  • 1
  • 1
candyline
  • 788
  • 8
  • 17
  • 1
    Awesome!! The only thing that worked for me so far!! Everyone answering same code but no one mentioned this anywhere. Thanks a ton for the trick buddy!! This should be accepted answer. – iUser Mar 05 '20 at 16:16
3

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])
       }
   }
}
Banghua Zhao
  • 1,518
  • 1
  • 14
  • 23
0

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])
        }
Shubham Mishra
  • 1,303
  • 13
  • 24
  • I've already tried that, tried once more. Doesn't work. As you can see in the image which I just uploaded, placeholder text colour doesn't change at all. – Raymond Oct 27 '19 at 18:01
  • 1
    This no longer works as of iOS 13. It worked on some earlier versions though. – Andy Ibanez Oct 29 '19 at 14:47
0

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)
Yogesh Patel
  • 1,893
  • 1
  • 20
  • 55
  • Use of unresolved identifier 'Label'. What is Label here? – Raymond Oct 29 '19 at 16:29
  • Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<.CustomUISearchBar 0x7fd27471cf90> valueForUndefinedKey:]: this class is not key value coding-compliant for the key placeholderLabel.' – Raymond Oct 29 '19 at 16:54
0

You need to style everything in viewDidAppear