Swift: UISegmentedControl 选定部分的背景颜色更改

Swift: Background color change in selected segment of UISegmentControl

在我的 Swift 应用程序中,我不知道如何在 UISegmentControl 中单独更改选定段的 BGColor。我已经尝试了很多,只有色调在变化。我在 Objective - C 中取得了成功。我不知道如何将其转换为 SWIFT。请指导我。我的代码如下:

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
    }
}
}

输出

您的更改颜色代码工作正常,唯一的问题是条件是否以与 objective c 相同的方式工作。

改变条件

 if(sender.selectedSegmentIndex != i)

@IBAction func action(sender: UISegmentedControl) {
    for(var i : Int = 0; i < sender.subviews.count; i++)
    {
        if(sender.selectedSegmentIndex != i)
        {
            //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
        }
    }
}

Swift 代码的问题在于对可选项的处理: 即使 isSelected 为假,(sender.subviews[i].isSelected) != nil 也将为真。

尝试使用 Swift 语法编写循环

for subview in (sender.subviews as! [UIView]) {
   if (subview.isSelected) {
       subview.tintColor = UIColor.redColor()
   } 
   else {
       subview.tintColor = nil
   } 
}

至少在该循环中,您实际上是在测试子视图是否被选中,而不是视图是否为 nil。

根据@MiKL 的建议,以下代码运行良好。

代码

for(var i : Int = 0; i < sender.subviews.count; i++)
        {
            if ((sender.subviews[i].isSelected) == true)
            {
                (sender.subviews[i] as! UIView).tintColor = UIColor .redColor()
            }
            else
            {
                (sender.subviews[i] as! UIView).tintColor = nil
            }
        }

我尝试使用 isSelected,它给我一个错误,提示该方法不存在。这是不使用 isSelected 方法的另一种方法

使用 UISegmentControl 的值更改事件按其原始 x 值对段进行排序,然后循环并比较 selectedSegmentIndex 属性。这是一个假设 4 段的分段控制的示例:

@IBAction func indexChanged(sender: UISegmentedControl) {

    let sortedViews = sender.subviews.sort( { [=10=].frame.origin.x < .frame.origin.x } )

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

}

然后在 viewDidLoad 中为最初选择的段设置 tintColor,在本例中它是第一个:

let sortedViews = segmentedControlOutletVariable.subviews.sort( { [=11=].frame.origin.x < .frame.origin.x } )
sortedViews[0].tintColor = UIColor.blueColor()

对于Swift: 在段控件上单击 (@IBAction) 使用以下代码

@IBAction func segmentChanged(sender: UISegmentedControl) {
    let sortedSubViews = sender.subviews.sort { [=10=].frame.minX < .frame.minX }
    let selectedSegment = sortedSubViews[sender.selectedSegmentIndex]
    sortedSubViews.forEach({
        // white is selected color and cayan color is for not selected item 
        [=10=].tintColor = [=10=] == selectedSegment ? UIColor.whiteColor() : UIColor.cyanColor()
    })
}

创建 segmentedControl 的出口,在 viewDidLoad 上你需要调用上面的函数。

self.segmentChanged(segmentedControl)

更新@gabo 在Swift 4.1 中的回答,因为我无权修改他的回答。

@IBAction func indexChanged(sender: UISegmentedControl) { 

     let sortedViews = sender.subviews.sorted( by: { [=10=].frame.origin.x < .frame.origin.x } )

            for (index, view) in sortedViews.enumerated() {
                if index == sender.selectedSegmentIndex { //When selected
                    view.tintColor = UIColor.blue
                } else {//Unselected
                    view.tintColor = nil
                }
            }

}

最初在 viewDidLoad

中选择的片段
let sortedViews = segmentedControlOutletVariable.subviews.sorted( by: { [=11=].frame.origin.x < .frame.origin.x } )
sortedViews[0].tintColor = UIColor.blue //Default Selection color

Swift 4

let sortedViews = segmentedControl.subviews.sorted( by: { [=10=].frame.origin.x < .frame.origin.x } )

for (index, view) in sortedViews.enumerated() {
    if index == segmentedControl.selectedSegmentIndex {
        view.tintColor = UIColor.red
    } else {
        view.tintColor = UIColor.green
    }
}

iOS 13 和 Swift 5

尝试使用此扩展程序:

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;
        }
    }
}

致电:

segmentedControlName.setSelectedSegmentForegroundColor(.white, andTintColor: .black);

我希望突出显示的每个段都有不同的颜色,并找到了一个非常简单的解决方案答案,这只是简单地更改 Switch 中每个 Case 上的 selectedSegmentTintColor 的颜色。

这是使用 Swift 5.1

@IBOutlet weak var mySegOutlet: UISegmentedControl!


@IBAction func mySegmentControl(_ sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
    case 0:
        mySegOutlet.selectedSegmentTintColor = .red

    case 1:
        mySegOutlet.selectedSegmentTintColor = .yellow

    case 2:
        mySegOutlet.selectedSegmentTintColor = .white

    case 3:
        mySegOutlet.selectedSegmentTintColor = .orange

    case 4:
        mySegOutlet.selectedSegmentTintColor = .red

    default:
        break
    }  //end of Switch
}

记得在 ViewDidLoad 中设置文本颜色 - 颜色混合很重要。

mySegOutlet.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.selected)

这对我来说非常顺利,给我带来了圆角和漂亮视觉效果的理想结果,而且你没有设置 Segment 的背景颜色,因此你不需要重置背景离开线段时的颜色。