Funnycuni
Funnycuni

Reputation: 379

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.

Upvotes: 6

Views: 1902

Answers (3)

Dejan Skledar
Dejan Skledar

Reputation: 11435

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.

Upvotes: 3

Nullable
Nullable

Reputation: 994

I guess the reason why it doesn't work is probably the searchController.searchBar.searchTextField = nil you got.

searchTextField is a new property for iOS 13, which can be done if you only support >= iOS 13. If you want to adapt to the previous version of iOS 13, you can traverse UISearchBar to find UISearchBarTextField and directly set the found UISearchBarTextField.

The code I looked up is probably like this, I put it in the Category of UIView.

- (UIView *)findChildViewClass:(Class)childViewClass fromView:(UIView *)fromView{
    for (UIView *subView in fromView.subviews) {
        if ([subView isMemberOfClass:childViewClass]) {
            return subView;
        }
        UIView *finalView = [self findChildViewClass:childViewClass fromView:subView];
        if (finalView) {
            return finalView;
        }else{
            continue;
        }
    }
    return nil;
}

When used, you can customize a searchTextField property to inherit from UITextField to save the found value.

_searchTextField = (UITextField *)[searchBar findChildViewClass:NSClassFromString(@"UISearchBarTextField") fromView: searchBar];

This is what I use now, it is working, I hope to be useful to you.

Upvotes: 0

Ashish
Ashish

Reputation: 726

you can set this with UITextField appearance property. check this line of code

 UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

Upvotes: 0

Related Questions