Jasmin
Jasmin

Reputation: 193

How do I set different widths on scope buttons in UISearchBar?

I have a little problem and didn't found any solution yet.

I have a UISearchBar with a ScopeBar in my application. The ScopeBar includes 4 scope buttons. All of them have an equal width at the moment.

One of my buttons has a longer text than the others. In my case, the text gets truncated. It looks something like:

[  short  |  short  |longte...|  short  ]

There would be no problem to show the whole text, if i could minimize the width of the short buttons and add some pixels to the third button.

First question: Is it possible to set different button sizes?

Second one: If yes, how could I do that?

Upvotes: 2

Views: 961

Answers (1)

Guillaume Algis
Guillaume Algis

Reputation: 11016

I don't think its possible to access the properties of the UISegmentedControl (scope bar) directly from the UISearchBar using the public APIs.

One way to work around this is to access the UISegmentedControl is to use a private property of the UISearchBar: _scopeBar.

A clean way to do so would be to declare a category on UISearchBar to expose this property:

@interface UISearchBar (ExposeScopeBar)

@property (readonly) UISegmentedControl *_scopeBar;

@end

Then all you have to do is access the scope bar (which is a classic UISegmentedControl), and set its apportionsSegmentWidthsByContent property to true:

self.searchBar._scopeBar.apportionsSegmentWidthsByContent = YES;

scope bar after modifications

You could also use the -setWidth:forSegmentAtIndex: method of UISegmentedControl if you need more fine-grained control on the segment size.

Keep in mind though that this uses a private UIKit API, and there's a change your app will be rejected from the App Store.


Another option would be to search recursively for the UISegmentedControl in the UISearchBar view hierarchy instead of using the private property.

Here's a pseudo code snippet to do this:

- (UISegmentedControl *)scopeBarForSearchBar:(UISearchBar *)searchBar
{
    return [self scopeBarInViewHierarchy:searchBar];
}

- (UISegmentedControl *)scopeBarInViewHierarchy:(UIView *)view
{
    if ([view isKindOfClass:[UISegmentedControl class]])
    {
        return view;
    }

    for (UIView *child in [view subviews])
    {
        UIView *result = [self scopeBarInViewHierarchy:child];
        if (result)
        {
            return result;
        }
    }
    return nil;
}

Again: This is pseudo-code. Untested.

This solution does not make usage of private APIs, so it should pass the App Store validation without issue.

Upvotes: 2

Related Questions