Search code examples
iosswiftbordercustomizationuisegmentedcontrol

How to customize UISegmentedControl to change selected segment bottom border?


I want to customize UISegmentedControl like this image:

enter image description here


Solution

  • Use extension with this self.segmentController.customizeAppearance(for: 1)

    Call addBorder method and pass your UISegmentedControl as a parameter

        static func addBorder(_ uiSegmentControl: UISegmentedControl){
    
        var upperBorder: CALayer = CALayer()
        upperBorder.backgroundColor = UIColor.init(red: 255.0, green:255.0, blue: 255.0, alpha: 1.0).cgColor
        upperBorder.frame = CGRect(x: 0, y: Int(ceil(uiSegmentControl.subviews[0].bounds.height))-1, width: Int(floor(uiSegmentControl.bounds.width)), height: 1)
        uiSegmentControl.layer.addSublayer(upperBorder)
    
        for i in 0..<uiSegmentControl.subviews.count {
    
            if i == uiSegmentControl.selectedSegmentIndex {
                upperBorder = CALayer()
                upperBorder.backgroundColor = UIColor.init(red: 215/255.0, green: 0.0, blue: 30/255.0, alpha: 1.0).cgColor
                upperBorder.frame = CGRect(x: i*Int(ceil(uiSegmentControl.subviews[i].bounds.width)), y: Int(ceil(uiSegmentControl.subviews[i].bounds.height))-1, width: Int(floor(uiSegmentControl.subviews[i].bounds.width)), height: 1)
                uiSegmentControl.layer.addSublayer(upperBorder)
            }
        }
    
    }
    
    extension UISegmentedControl {   
    func customizeAppearance(for height: Int) {
        setDividerImage(UIImage().colored(with: .clear, size: CGSize(width: 1, height: height)), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
        setBackgroundImage(UIImage().colored(with: .clear, size: CGSize(width: 1, height: height)), for: .normal, barMetrics: .default)
      }
    }
    extension UIImage {
        func colored(with color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContext(size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor);
        let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size)
        context!.fill(rect);
        let image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image!
    }