SelectedTintColor of Segment Control is not rounded corner on iOS 13

后端 未结 5 1269
迷失自我
迷失自我 2021-02-06 12:49

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:

cla         


        
相关标签:
5条回答
  • 2021-02-06 12:53

    Swift 5

    If you use a subclass:

    override func layoutSubviews() {
        super.layoutSubviews()
        roundCorners(radius: frame.height / 2)
    
        if #available(iOS 13.0, *) {
            selectedSegmentTintColor = .clear
        } else {
            tintColor = .clear
        }
    
        for (index, subview) in subviews.enumerated() {
            if ((subviews[index] as? UIImageView) != nil) && index == selectedSegmentIndex {
                subview.backgroundColor = .white
                subview.roundCorners(radius: subview.frame.height / 2)
            } else {
                subview.backgroundColor = .clear
            }
        }
    }
    
    private func roundCorners(radius: CGFloat) {
        layer.roundCorners(radius: radius)
        self.clipsToBounds = true
    }
    

    If you use the default segmented control, you just prefix with name of your segmented control:

    mySegmentedControl.selectedSegmentTintColor = .clear
    
    for (index, subview) in mySegmentedControl.subviews.enumerated() {
       .....
    }
    
    0 讨论(0)
  • 2021-02-06 12:54

    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.

    0 讨论(0)
  • 2021-02-06 13:02

    this code works for me iOS 13 - Swift 5.1

        segment.layer.cornerRadius = 12
        segment.layer.borderWidth = 1
        segment.layer.borderColor = UIColor.black.cgColor
        segment.font(name: "TheSans-Plain", size: 14)
        segment.clipsToBounds = true
        segment.layer.masksToBounds = true
    
        if #available(iOS 13.0, *) {
            segment.selectedSegmentTintColor = .red
        } 
    
    0 讨论(0)
  • 2021-02-06 13:03

    Make a custom class for segment

    class CustomSegmentedControl: UISegmentedControl {
    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = self.bounds.size.height / 2.0
        layer.borderColor = use_your_custom_color
        layer.borderWidth = 1.0
        layer.masksToBounds = true
        clipsToBounds = true
        for i in 0...subviews.count - 1{
            if let subview = subviews[i] as? UIImageView{
                if i == self.selectedSegmentIndex {
                    subview.backgroundColor = use_your_custom_color
                }else{
                    subview.backgroundColor = .white
                }
            }
        }
    }}
    

    May be this will easy to use like this

       @IBOutlet weak var reminderSegmentControl: CustomSegmentedControl!
    
    0 讨论(0)
  • 2021-02-06 13:10

    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.

    0 讨论(0)
提交回复
热议问题