Question

Has anyone managed to color the scopebar portion of a UISearchBar, it has a tintColor property but setting it does not affect the attached scopebar UISegmentedControl. Ive got a handle on the bar to tint it but doesnt seem to work ie:

for (id subview in searchBar.subviews){
  if([subview isMemberOfClass:[UISegmentedControl class]]){
     UISegmentedControl *scopeBar=(UISegmentedControl *) subview;
    scopeBar.tintColor=UIColorFromRGB(0x990066);
 }
}

Cheers, Neil

Was it helpful?

Solution

This is interesting, turns out the scope bar is a somewhat customised segmented control.

From the docs: UISegmentedControl uses this property only if the style of the segmented control is UISegmentedControlStyleBar.

Now the scope bar segmented control looks like UISegmentedControlStyleBar but isn't, it's some undocumented style:

NSLog(@"scope bar style is %d", scopeBar.segmentedControlStyle);
> scope bar style is 7

You can try this, which does actually set the tint but it looks like arse:

[scopeBar setSegmentedControlStyle:UISegmentedControlStyleBar];
[scopeBar setTintColor: UIColorFromRGB(0x990066)];
> scope bar style is 2

Internally there are some instance variables influencing this: _segementedControlFlags.style and _barStyle but you cannot hack those unless you bypass the sanctioned API.

The best course of action is to raise it with Apple and hope they include a fix in a future release.

OTHER TIPS

The above approaches weren't working for me and I ended up using an iOS appearance method.

[[UISegmentedControl appearanceWhenContainedIn:[UISearchBar class], nil] setTintColor:[UIColor whiteColor]];

Here's some copy paste friendly code for what the others are discussing.

scopeBar.segmentedControlStyle = UISegmentedControlStyleBar; //required for color change
for (id subview in self.searchDisplayController.searchBar.subviews )
{
    if([subview isMemberOfClass:[UISegmentedControl class]])
    {
        UISegmentedControl *scopeBar=(UISegmentedControl *) subview;
        scopeBar.tintColor =  [UIColor blackColor];         
    }
}

If you a white box like area around your buttons, you can change the color of that through interface builder.

I wouldn't say it looks "like ass" as the others do, but it isn't really ideal either.

Simply do the following to change the tint color of ScopeBar:

The below code is in C# (Xamarin)

SearchController.SearchBar.TintColor = UIColor.Green;

I have not been able to get the tint set reliably for a scope bar.

What I've ended up doing is changing the search bar's tintColor ... UNTIL transitioning into search mode, at which point I make it the default color to match the scope bar. Then, when canceling the search, I change it back.

One spot that I seem to be missing here is the transition that occurs when the corresponding tableView is tapped, causing the search bar to lose first responder status. In that case, the color does not change back. Reason: I base that color change on having the search bar's cancel button being clicked.

Knee-jerk reaction: searchBarCancelButtonClicked: should get called (wherein we change back the tint) ... but that can't be right, because Cancel wasn't clicked. I really need a "Search is done" type of detection. Maybe just keep an eye on first responder and see when UISearchBar moves in and out of that state?

Another band-aid solution to this problem (and a less complicated one) is you could add a semi-transparent UIImageView over the top of the Search bar and Scope bar and change the background color of the UIImageView to your desired tint color.

enter image description here

Change the tint color for changing color of scope bar. Note BarTintColor is different - this will change the color of the search bar..

This solution is in Swift, can be adapted to objective-c. You can find the segmented control view using below function

func findSegmentedControl(view : UIView) -> UIView? {
    for v in view.subviews {
        if v is UISegmentedControl {
            print(v)
            return v
        } else {
            if let found = findSegmentedControl(view : v) {
                return found
            }
        }
    }
    return nil
}

and then set tint color of the view. calling this function will be like this:

if let segmentedView = findSegmentedControl(view: searchController.searchBar) {                
            segmentedView.tintColor = UIColor.white
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top