How to remove border from segmented control

How to remove the outer border of a segmented control? I set the divider image to what I wanted, but now, to follow the layout of my application, I need to have a segmented control with no outer border.

+18
ios swift xcode6 uisegmentedcontrol
source share
8 answers

What you need to understand is that the backgroundColor property is not stateful. Therefore, you should use setBackgroundImage(_:for:barMetrics:) .

We can easily remove both borders and delimiters using the function below.

For Swift 3 & 4+:

 extension UISegmentedControl { func removeBorders() { setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default) setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default) setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) } // create a 1x1 image with this color private func imageWithColor(color: UIColor) -> UIImage { let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() context!.setFillColor(color.cgColor); context!.fill(rect); let image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image! } } 

For Swift 2.2:

 extension UISegmentedControl { func removeBorders() { setBackgroundImage(imageWithColor(backgroundColor!), forState: .Normal, barMetrics: .Default) setBackgroundImage(imageWithColor(tintColor!), forState: .Selected, barMetrics: .Default) setDividerImage(imageWithColor(UIColor.clearColor()), forLeftSegmentState: .Normal, rightSegmentState: .Normal, barMetrics: .Default) } // create a 1x1 image with this color private func imageWithColor(color: UIColor) -> UIImage { let rect = CGRectMake(0.0, 0.0, 1.0, 1.0) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillRect(context, rect); let image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image } } 

Call the above function.

 segmentedControl.removeBorders() 

Link: Remove UISegmentedControl delimiters completely. (iphone)

Thanks https://stackoverflow.com/users/3921490/amagain for version Swift 3.

+53
source share

Here's a quick version of Sohil 3 that might help someone else. It helps me.:)

 extension UISegmentedControl { func removeBorders() { setBackgroundImage(imageWithColor(color: backgroundColor!), for: .normal, barMetrics: .default) setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default) setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) } // create a 1x1 image with this color private func imageWithColor(color: UIColor) -> UIImage { let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() context!.setFillColor(color.cgColor); context!.fill(rect); let image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image! } } 
+11
source share

Hope this helps someone

Swift - 4

Make the background color and hue of your Segment control the same. Then "set titleTextAttributes" of your segment control

  segmentedControl.tintColor = UIColor.red segmentedControl.backgroundColor = UIColor.red let attributes = [NSAttributedStringKey.foregroundColor: UIColor.white] segmentedControl.setTitleTextAttributes(attributes, for: .normal) segmentedControl.setTitleTextAttributes(attributes, for: .selected) 
+6
source share

If you want to keep borders between cells

 extension UISegmentedControl { func removeBorders() { if let backgroundColor = backgroundColor, let backgroundImage = UIImage.imageWithSize(size: CGSize.one_one, color: backgroundColor){ setBackgroundImage(backgroundImage, for: .normal, barMetrics: .default) } if let tintColor = tintColor, let tintImage = UIImage.imageWithSize(size: CGSize.one_one, color: tintColor){ setBackgroundImage(tintImage, for: .selected, barMetrics: .default) setDividerImage(tintImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) } } } extension CGSize{ static var one_one: CGSize{ return CGSize(width: 1.0, height: 1.0) } } extension UIImage{ static func imageWithSize(size : CGSize, color : UIColor = UIColor.white) -> UIImage? { var image:UIImage? = nil UIGraphicsBeginImageContext(size) if let context = UIGraphicsGetCurrentContext() { context.setFillColor(color.cgColor) context.addRect(CGRect(origin: CGPoint.zero, size: size)); context.drawPath(using: .fill) image = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext() return image } } 
+2
source share

Swift 5.x:

This solution removes only the outer border and keeps a rounded angular on each button

 extension UISegmentedControl { func removeBorders(andBackground:Bool=false) { setBackgroundImage(imageWithColor(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default) setBackgroundImage(imageWithColor(color: tintColor!), for: .selected, barMetrics: .default) setDividerImage(imageWithColor(color: UIColor.clear), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) _ = self.subviews.compactMap { if ($0.frame.width>0) { $0.layer.cornerRadius = 8 $0.layer.borderColor = UIColor.clear.cgColor $0.clipsToBounds = true $0.layer.borderWidth = andBackground ? 1.0 : 0.0 $0.layer.borderColor = andBackground ? tintColor?.cgColor : UIColor.clear.cgColor andBackground ? $0.layer.backgroundColor = UIColor.clear.cgColor : nil } } } // create a 1x1 image with this color private func imageWithColor(color: UIColor) -> UIImage { let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext() context!.setFillColor(color.cgColor); context!.fill(rect); let image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image! } } 

Using:

 mySegmentedControl.removeBorders() 
+1
source share

Perhaps you have a use case in which you do not want the rounded border to not be displayed if it is embedded in the cell. In this case, set the automatic placement constraints to -2, and the border will be hidden, since it will go beyond the borders of the cell.

0
source share

If you only need segment control with texts, use,

 segmentControl.backgroundColor = .clear segmentControl.tintColor = .clear let attributes: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.white] segmentControl.setTitleTextAttributes(attributes, for: .normal) let selectedAttrib: [NSAttributedString.Key : Any] = [.font : UIFont(family: .medium, ofSize: 13)!, .foregroundColor : UIColor.red] segmentControl.setTitleTextAttributes(hightLightedStateAttrib, for: .selected) 

NB: I googled it for a long time, so I posted here.

Source: CodeMentor

0
source share
  • The accepted answer works to get rid of the border.
  • The solution mentioned here also works to disable a segmented control.

However, combining the two solutions, I could not get the correct selected segment in the disabled state.

When I selected a segment and made a network call, I wanted to disable the segmented control.

The result was like this:

enter image description here

What was desired was:

enter image description here

The only complement to the Sohil solution is:

 setBackgroundImage(imageWithColor(color: imageWithColor(color: tintColor)), for: [.selected, .disabled], barMetrics: .default) 

After the selected && disabled segment will have the correct color.

0
source share

All Articles