Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change text color of PlaceHolder in UISearchBar? (iOS 13)

After looking for updated (iOS 13) answers, I didn't find any solutions to this simple problem :

How to change the textColor of the placeholder in an UISearchBar ?

My app doesn't handle Light/Dark mode. I don't want the system to change my UIPlaceHolder text color. I want it to be always white.


    if #available(iOS 13.0, *) {
        let attrString = NSMutableAttributedString(string: "My PlaceHolder")
        attrString.addAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], range: NSRange(location: 0, length: attrString.length))
        searchController.searchBar.searchTextField.attributedPlaceholder = attrString
    }

I expected this code to work. I thought the new property searchTextField would have made it easier to customize my UISearchBar.

EDIT:

This code kind of works in the viewDidAppear method :

if #available(iOS 13.0, *) {
     searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "My PlaceHolder", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white.withAlphaComponent(0.80)])
 }

The issue is that the color is changing when you scroll up and down.

like image 415
Funnycuni Avatar asked Oct 08 '19 13:10

Funnycuni


People also ask

How do I change the search bar color in Swift?

Change Search Bar Default Image Color The left hand default search image in UISearchBar represents the left view of the UITextField. The Image is rendered to change it to the desired colour. @IBOutlet weak var searchBar: UISearchBar! Hope it will help you in customising the UISearchBar in your app.


1 Answers

As you already mentioned, your code works only in viewDidAppear, which makes the placeholder to flicker from the default gray color to the preferred color.

However, there seem to be a time before viewDidAppear (I couldn't figure it out when exactly), to change the placeholder before the view actually appears.

I suppose, this may be connected to how iOS handles light/dark mode and/or an iOS bug.

The solution I came out with that works around the issue:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if #available(iOS 13.0, *) {
        let placeholder = NSAttributedString(string: "Search",
                                             attributes: [
                                                .foregroundColor: UIColor.white
        ])
        let searchTextField = searchBar.searchTextField

        // Key workaround to be able to set attributedPlaceholder
        DispatchQueue.global().async {
            DispatchQueue.main.async {
                searchTextField.attributedPlaceholder = placeholder
            }
        }
    }
}

There seem to be no performance and/or other downside to this method.

If anybody else comes with a better approach, feel free to collaborate.

like image 167
Dejan Skledar Avatar answered Oct 14 '22 07:10

Dejan Skledar