Rounded corner is working great on iOS 12 and below, but it's broken on iOS 13. I've created a custom Segment control class.
Code:
class SegmentedControl: UISegmentedControl {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = self.bounds.size.height / 2.0
layer.borderColor = UIColor(red: 170.0/255.0, green: 170.0/255.0, blue: 170.0/255.0, alpha: 1.0).cgColor
layer.borderWidth = 1.0
layer.masksToBounds = true
clipsToBounds = true
}
}
I've gone through this post - How to change the colors of a segment in a UISegmentedControl in iOS 13? but I couldn't get any solution.
Screenshot:
I was facing the same issue on iOS 13. Then I dug into its view hierarchy then I found it has multiple subviews. So I made a trick for iOS 13. You have to do following changes for iOS 13 -
selectedSegmentTintColor
to Clear
- self.selectedSegmentTintColor = .clear
Add following code snippet inside layoutSubviews
-
for i in 0...subviews.count - 1{
if let subview = subviews[i] as? UIImageView{
if i == self.selectedSegmentIndex {
subview.backgroundColor = UIColor(red: 170.0/255.0, green: 170.0/255.0, blue: 170.0/255.0, alpha: 1.0)
}else{
subview.backgroundColor = .clear
}
}
}
I hope it will help you.
Similar to other solution I have Following Sub-Class Segment control
UISegmentedControl
Which gives following result -
class OYSegmentControl: UISegmentedControl {
override func layoutSubviews(){
super.layoutSubviews()
let segmentStringSelected: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.font : UIFont.fontActionLabel(ofSize: 14.0),
NSAttributedString.Key.foregroundColor : UIColor.white
]
let segmentStringHighlited: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.font : UIFont.fontActionLabel(ofSize: 14.0),
NSAttributedString.Key.foregroundColor : #colorLiteral(red: 0.5567105412, green: 0.5807551742, blue: 0.6022000909, alpha: 1)
]
setTitleTextAttributes(segmentStringHighlited, for: .normal)
setTitleTextAttributes(segmentStringSelected, for: .selected)
setTitleTextAttributes(segmentStringHighlited, for: .highlighted)
layer.masksToBounds = true
if #available(iOS 13.0, *) {
selectedSegmentTintColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
} else {
tintColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
}
backgroundColor = #colorLiteral(red: 0.9191747308, green: 0.9334954619, blue: 0.9506797194, alpha: 1)
//corner radius
let cornerRadius = bounds.height / 2
let maskedCorners: CACornerMask = [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner]
//background
clipsToBounds = true
layer.cornerRadius = cornerRadius
layer.maskedCorners = maskedCorners
let foregroundIndex = numberOfSegments
if subviews.indices.contains(foregroundIndex),
let foregroundImageView = subviews[foregroundIndex] as? UIImageView {
foregroundImageView.image = UIImage()
foregroundImageView.clipsToBounds = true
foregroundImageView.layer.masksToBounds = true
foregroundImageView.backgroundColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
foregroundImageView.layer.cornerRadius = bounds.height / 2 + 5
foregroundImageView.layer.maskedCorners = maskedCorners
}
}
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}
Language: Swift 5.1
NOTE: This only works if you have outlet / frame set from Storyboard. Frame from code will cause issues. The extra 5 px on cornerRadius,a hack to make it better round rect. I ended up using - https://github.com/alokc83/MASegmentedControl as my use-case was from Code only view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With