Question

Is there a way of get rid of UISegmentedControl's rounded corners or it is the default behavior?

Was it helpful?

Solution

No, there is no API that gives you control over the layout of the segments.

You could probably try looking into the UISegmentedControl's view.subviews and try to change them according to your needs. But from personal experience I would not advice that. If Apple changed their order in the future your app will probably crash. The easiest thing to do is to create custom UIButtons that behave as toggle-buttons and control them like a UISegmentedControls (for toggle-buttons see How to use a UIButton as a toggle switch).

OTHER TIPS

There's something really easy that you can do to rid yourself of the rounded junk on the UISegmentedControl ... change the style to "7". I'm not joking. I just figured this out:

    // Magic number ... (it's cheating, but it works)
  mySegmentedBar.segmentedControlStyle = 7;  

This is the same control style they use in the UISearchBar's scope bar, like this:

Search Bar With Scope

But if someone only wants the scope bar, without the search, they're usually stuck with UISegmentedControl junk like this (with rounded corners):

BarStyle

Or worse, this...

BezeledStyle

Thankfully, by switching to bar style "7", we get the exact look of the stop bar, without all the subclassing and drawRect hackery:

enter image description here

If you wanted a different look you could just subclass it and do your own drawing in -drawRect:. See the Quartz 2D Programming Guide for reference on drawing with Quartz/Core Graphics.

By adding a border with reasonable width you can get the squared look:

self.segmentedControl.tintColor = [UIColor brownColor];
self.segmentedControl.layer.cornerRadius = 0.0;
self.segmentedControl.layer.borderColor = [UIColor brownColor].CGColor;
self.segmentedControl.layer.backgroundColor = [UIColor colorWithWhite:1 alpha:0.75].CGColor;
self.segmentedControl.layer.borderWidth = 1.5f;
self.segmentedControl.layer.masksToBounds = YES;

After lots of tries I got below solution which works fine without any background image or subclassing:

    mySegmentedControl.tintColor = [UIColor clearColor]; //Clear all border

    //Draw your own border
    mySegmentedControl.layer.borderColor = [UIColor blackColor].CGColor;
    mySegmentedControl.layer.borderWidth = 1.0;

    //Set tint color for selected subview
    UIColor *tintcolor=[UIColor redColor];
    int subViewIndex = 0; //index which is selected
    [[_segmentControl.subviews objectAtIndex:subViewIndex] setTintColor:tintcolor]; 

If someone's still interested, here's the simple extension in Swift 4 (iOS 11). Just make sure you set tint color before calling this method. If you change tint color after, make sure to call this method again :

extension UISegmentedControl {

func ignoreCornerRadius() {

    let renderer = UIGraphicsImageRenderer(size: bounds.size)

    let normalImage = renderer.image { (context) in
        tintColor.setStroke()
        context.stroke(bounds)
    }
    let selectedImage = renderer.image { (context) in
        tintColor.setFill()
        context.fill(bounds)
    }

    setBackgroundImage(normalImage, for: .normal, barMetrics: .default)
    setBackgroundImage(selectedImage, for: .selected, barMetrics: .default)

}

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top