6

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)?

Aleksander
  • 2,735
  • 5
  • 34
  • 57
  • just use uiview instead of uitoolbar – sim Jun 15 '15 at 17:40
  • @sim that's what I'm trying to avoid, but I might have to fall back on that if there's no way to make this work – Aleksander Jun 15 '15 at 17:42
  • In this case you need to setup width of the uisegmentcontroller in code and handle device orientation changes to update its width, I think its harder then just use uiview with autolayout – sim Jun 15 '15 at 17:49
  • Yeah you're probably right. The only drawback to using a `UIView` is that there's so much customization needed to make it behave like a `UIToolbar`. But I guess it's easier than handling the sizing manually. – Aleksander Jun 15 '15 at 17:53

2 Answers2

7

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

erparker
  • 1,301
  • 10
  • 21
  • 1
    willrotatetointerfaceorientation is deprecated – sim Jun 15 '15 at 18:00
  • This is actually a great solution. I don't even know if updating the width of the `UISegmentedControl` is necessary anymore because this looks pretty damn good. – Aleksander Jun 15 '15 at 20:49
5

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    
Sega-Zero
  • 3,034
  • 2
  • 22
  • 46
  • I will try your solution when I get back to my computer, and update the accepted answer if this turns out to work. Just a little tip: IBOutlets should be `weak`, not `strong` :) – Aleksander Jun 15 '15 at 20:50
  • I've just copy/pasted this from my sample project, that shouldn't be a problem i guess =) – Sega-Zero Jun 15 '15 at 21:01
  • Works perfectly !! on iOS 9.. thanks But I set IBOutlets to weak – Pierre Sep 13 '16 at 15:05
  • Apple recommends to use strong outlets since ios9, actually. see https://developer.apple.com/videos/play/wwdc2015/407/ – Sega-Zero Sep 13 '16 at 18:38