Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Background color change in selected segment of UISegmentControl

In my Swift app, I dont know how to change BGColor for selected segment alone, in UISegmentControl. I have tried a lot, only tint color is changing. I got success in Objective - C. I dont know how to convert that to SWIFT. Kindly guide me. My codings below:

Objective C

- (IBAction)mySeg:(UISegmentedControl *)sender {

    for (int i=0; i<[sender.subviews count]; i++)
    {
        if ([[sender.subviews objectAtIndex:i]isSelected] )
        {
            UIColor *tintcolor=[UIColor colorWithRed:255.0/255.0 green:0/255.0 blue:0/255.0 alpha:1.0];
            [[sender.subviews objectAtIndex:i] setTintColor:tintcolor];  //HERE SELECTED SEGMENT COLOR ALONE CHANGING
        }
        else
        {
            [[sender.subviews objectAtIndex:i] setTintColor:nil];
        }
    }
}

Swift

@IBAction func mySegAcn(sender: UISegmentedControl) {
for(var i : Int = 0; i < sender.subviews.count; i++)
{
    if((sender.subviews[i].isSelected) != nil) 
    {
        //var tint_Color =  UIColor(red: 1.0, green: 0, blue: 0, alpha: 1.0)

        (sender.subviews[i] as! UIView).tintColor = UIColor .redColor()  //HERE WHOLE TINT COLOR IS CHANGING
    }

    else
    {

        (sender.subviews[i] as! UIView).tintColor = nil
    }
}
}

Output

enter image description here

like image 367
McDonal_11 Avatar asked Sep 08 '15 06:09

McDonal_11


3 Answers

iOS 13 and Swift 5

Try using this extension:

extension UISegmentedControl {
    func setSelectedSegmentForegroundColor(_ foregroundColor: UIColor, andTintColor tintColor: UIColor) {
        if #available(iOS 13.0, *) {
            self.setTitleTextAttributes([.foregroundColor: foregroundColor], for: .selected)
            self.selectedSegmentTintColor = tintColor;
        } else {
            self.tintColor = tintColor;
        }
    }
}

Call:

segmentedControlName.setSelectedSegmentForegroundColor(.white, andTintColor: .black);
like image 59
Victor Rius Avatar answered Sep 27 '22 21:09

Victor Rius


Swift 4

let sortedViews = segmentedControl.subviews.sorted( by: { $0.frame.origin.x < $1.frame.origin.x } )

for (index, view) in sortedViews.enumerated() {
    if index == segmentedControl.selectedSegmentIndex {
        view.tintColor = UIColor.red
    } else {
        view.tintColor = UIColor.green
    }
}
like image 5
Abhishek Jain Avatar answered Nov 19 '22 10:11

Abhishek Jain


I tried using isSelected, it gives me an error saying the method does not exist. Here is another way to do it without the isSelected method

Use the value changed event for the UISegmentControl to sort the segments in order by their origin x value, then loop and compare the selectedSegmentIndex property. Here is an example with assuming a segmented control of 4 segments:

@IBAction func indexChanged(sender: UISegmentedControl) {

    let sortedViews = sender.subviews.sort( { $0.frame.origin.x < $1.frame.origin.x } )

    for (index, view) in sortedViews.enumerate() {
        if index == sender.selectedSegmentIndex {
            view.tintColor = UIColor.blueColor()
        } else {
            view.tintColor = UIColor.lightGrayColor()
        }
    }

}

Then in viewDidLoad set the tintColor for the initially selected segment, in this case it is the first:

let sortedViews = segmentedControlOutletVariable.subviews.sort( { $0.frame.origin.x < $1.frame.origin.x } )
sortedViews[0].tintColor = UIColor.blueColor()
like image 12
gabo Avatar answered Nov 19 '22 08:11

gabo