Search code examples
iosswiftswift3uisegmentedcontrol

how can I change the style for UISegmentedControl when it is selected by the user in Swift?


This is my UISegmentedControl written in Swift:

enter image description here

I created it with the following code:

let selectedAttributes: NSDictionary = [
        NSForegroundColorAttributeName: UIColor.black,
        NSFontAttributeName: fontForSegmentedControl!
    ]

    let normalAttributes: NSDictionary = [
        NSForegroundColorAttributeName: UIColor.gray,
        NSFontAttributeName: fontForSegmentedControl!
    ]

    mySegmentedControl.setTitleTextAttributes(selectedAttributes as [NSObject : AnyObject], for: UIControlState.selected)

    mySegmentedControl.setTitleTextAttributes(normalAttributes as [NSObject : AnyObject], for: UIControlState.normal)

and the extension for removing borders is here:

extension UISegmentedControl {
    func removeBorders() {
        setBackgroundImage(imageWithColor(color: UIColor.white/*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!
    }
}

But there's one thing wrong with it.

When I tap (and hold) the ONE or TWO it changes the background color to this (for the time it's being touched by user's finger):

enter image description here

I'm missing some code for changing style for selected (temporary pressed) option in UISegmentedControl.

How can I remove the dark grey selection and leave it with clear color?


Solution

  • Similar to how you have already set the background image for UIControlState.normal, you need to set appropriate images for UIControlState.highlighted and UIControlState.selected + UIControlState.highlighted.

    Add the following code to your extension function removeBorders() (assuming you want to have a clear background for pressed not selected segment and a tint colored background for pressed selected one):

    setBackgroundImage(imageWithColor(color: .clear), for: .highlighted, barMetrics: .default)
    setBackgroundImage(imageWithColor(color: tintColor!), for: [.selected, .highlighted], barMetrics: .default)