UIToolbar with UISegmentedControl AutoLayout (/full width)
Asked Answered
K

2

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

Kopple answered 15/6, 2015 at 17:26 Comment(4)
just use uiview instead of uitoolbarBromo
@Bromo 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 workKopple
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 autolayoutBromo
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.Kopple
B
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

Broderickbrodeur answered 15/6, 2015 at 17:55 Comment(2)
willrotatetointerfaceorientation is deprecatedBromo
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.Kopple
H
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    
Headwork answered 15/6, 2015 at 17:56 Comment(4)
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 :)Kopple
I've just copy/pasted this from my sample project, that shouldn't be a problem i guess =)Headwork
Works perfectly !! on iOS 9.. thanks But I set IBOutlets to weakFidellia
Apple recommends to use strong outlets since ios9, actually. see developer.apple.com/videos/play/wwdc2015/407Headwork

© 2022 - 2024 — McMap. All rights reserved.