UIToolbar with UISegmentedControl AutoLayout (/full width)

3.1k views Asked by At

I have a UIViewController with a UIToolBar below the UINavigationBar and a UITableView below that. The only UIBarButtonItem on my UIToolBar is a UISegmentedControl as in the screenshot below: enter image description here

However, how do I get the UISegmentedControl/UIBarButtonItem to stretch to fill the UIToolBar like in the App Store app? enter image description here

Keep in mind that I'm also supporting landscape mode, so it'll have to automatically stretch to fit the new width when the device is rotated. This is something I hoped to achieve with AutoLayout, but as far as I know I cannot use AutoLayout inside a UIToolBar.

Any suggestions (except for replacing the UIToolbar with a UIView)?

2

There are 2 answers

2
erparker On BEST ANSWER

I created a toolbar with a segmented control inside, then made the segmented control 320 wide. I then set flexible layout guides on each side to force the segmented control into the center. This looks fine in portrait, but the segmented control will not stretch out for landscape.

Portrait (includes IB setup and simulator) enter image description here

Landscape (also includes IB setup and simulator) enter image description here

It seems like the app store has a segmented control that is set to a certain width and then the view isn't allowed to rotate. I understand you would like the segmented control to change width with the layout, but unfortunately that's not possible with auto layout at the moment.

My suggestion would be, if you really wanted the segmented control to change width with rotation would be to programmatically set the width when the device rotates to landscape.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation))
    {            
        //set segmented control to landscape
    }

    if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation))
    {
        //set segmented control to portrait width
    }
}

One more thing, if you do end up using this device rotation stuff, you'll still need those flexible spacers in IB to keep your segmented control centered in the toolbar

4
Sega-Zero On

You can do that with code. Something like this:

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
@property (strong, nonatomic) IBOutlet UISegmentedControl *segment;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _segment.translatesAutoresizingMaskIntoConstraints = NO;
    [_toolbar addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[_segment]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_segment)]];
    [_toolbar addConstraint:[NSLayoutConstraint constraintWithItem:_segment
                                                         attribute:NSLayoutAttributeCenterY
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:_toolbar
                                                        attribute:NSLayoutAttributeCenterY
                                                       multiplier:1.
                                                          constant:0.]];
}

@end