Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SelectedTintColor of Segment Control is not rounded corner on iOS 13

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: enter image description here

like image 557
Amir Khan Avatar asked Oct 10 '19 04:10

Amir Khan


2 Answers

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 -

  1. ChangeselectedSegmentTintColor to Clear - self.selectedSegmentTintColor = .clear
  2. 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.

like image 130
Rajinderpal Singh Avatar answered Sep 30 '22 04:09

Rajinderpal Singh


Similar to other solution I have Following Sub-Class Segment control UISegmentedControl

Which gives following result -

enter image description here

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.

like image 42
Bishal Ghimire Avatar answered Sep 30 '22 04:09

Bishal Ghimire