UISegmentedControl 选定的段颜色

发布于 2024-08-21 20:39:12 字数 282 浏览 3 评论 0原文

有没有办法在UISegmentedControl中自定义所选段的颜色?

我找到了 segmentedController.tintColor 属性,它可以让我自定义整个分段控件的颜色。 问题是,当我为 tintColor 属性选择明亮的颜色时,选定的段几乎无法识别(其颜色几乎与分段控件的其余部分相同,因此很难区分选定和未选定的段)。所以我无法使用任何好的亮色来进行分段控制。 解决方案是选定段颜色的一些单独的属性,但我找不到它。有人解决这个问题了吗?

Is there any way to customize color of selected segment in UISegmentedControl?

I've found segmentedController.tintColor property, which lets me customize color of the whole segmented control.
The problem is, when I select bright color for tintColor property, selected segment becomes almost unrecognizable (its color is almost the same as the rest of segmented control, so its hard to distinguish selected and unselected segments). So I cannot use any good bright colors for segmented control.
The solution would be some separate property for selected segment color but I cannot find it. Did anyone solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

翻了热茶 2024-08-28 20:39:13

我发现我可以在子视图上使用与段具有相同索引的标签,这样无论顺序如何,段都会正确着色。

// In viewWillAppear set up the segmented control 

// then for 3 segments:  
self.navigationItem.titleView = segmentedControl;
//Order of subviews can change randomly!, so Tag them with same index as segment
[[[segmentedControl subviews]objectAtIndex:0]setTag:0]; 
[[[segmentedControl subviews]objectAtIndex:1]setTag:1];
[[[segmentedControl subviews]objectAtIndex:2]setTag:2];


// color follows the selected segment
- (IBAction)mySelector:(id)sender {
selector = [sender selectedSegmentIndex]
  for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
  }
}

// in viewDidAppear for returning to the view
[segmentedControl setSelectedSegmentIndex:selector];
for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
}

I found I could use tag on the subviews with the same index as the segments, so that in any order they the segments will be colored correctly.

// In viewWillAppear set up the segmented control 

// then for 3 segments:  
self.navigationItem.titleView = segmentedControl;
//Order of subviews can change randomly!, so Tag them with same index as segment
[[[segmentedControl subviews]objectAtIndex:0]setTag:0]; 
[[[segmentedControl subviews]objectAtIndex:1]setTag:1];
[[[segmentedControl subviews]objectAtIndex:2]setTag:2];


// color follows the selected segment
- (IBAction)mySelector:(id)sender {
selector = [sender selectedSegmentIndex]
  for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
  }
}

// in viewDidAppear for returning to the view
[segmentedControl setSelectedSegmentIndex:selector];
for (id seg in [segmentedControl subviews]) {
    for (id label in [seg subviews]) {
        if ([seg tag] == selector){
            [seg setTintColor:selectedColor];
        } else {
            [seg setTintColor:nonSelectedColor];
        }
    }
}
謸气贵蔟 2024-08-28 20:39:13

在段之间切换时,前两个解决方案对我不起作用。

我的解决方案是在视图控制器中处理段更改事件,然后在每次更改段时调用此方法:

+ (void)setSegmentedControl:(UISegmentedControl *)segmentedControl 
              selectedColor:(UIColor *)selectedColor 
            deselectedColor:(UIColor *)deselectedColor
{
    for (int i = 0; i < segmentedControl.subviews.count; i++) 
    {
        id subView = [segmentedControl.subviews objectAtIndex:i];

        if ([subView isSelected])
            [subView setTintColor:selectedColor];
        else
            [subView setTintColor:deselectedColor];
    }    
}

The top two solutions didn't work for me when switching between segments.

My solution was to handle the segment change event in my view controller and then call this method each time the segment is changed:

+ (void)setSegmentedControl:(UISegmentedControl *)segmentedControl 
              selectedColor:(UIColor *)selectedColor 
            deselectedColor:(UIColor *)deselectedColor
{
    for (int i = 0; i < segmentedControl.subviews.count; i++) 
    {
        id subView = [segmentedControl.subviews objectAtIndex:i];

        if ([subView isSelected])
            [subView setTintColor:selectedColor];
        else
            [subView setTintColor:deselectedColor];
    }    
}
Bonjour°[大白 2024-08-28 20:39:13

我想知道为什么有人没有提到 UIAppearanceProxy

Apple Doc::

https://developer.apple.com/documentation/uikit/uisegmentedcontrol#1653545

示例代码:

    private class func applyUISegmentControlAppearance(){
    let apperance = UISegmentedControl.appearance()

    // Set Navigation bar Title colour
    let unselAttrib = [NSForegroundColorAttributeName:UIColor.yellow,
                                        NSFontAttributeName: UIFont.systemFont(ofSize: 15)]

    let selAttrib = [NSForegroundColorAttributeName:UIColor.red,
                     NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)]


    apperance.setTitleTextAttributes(unselAttrib, for: .normal)
    apperance.setTitleTextAttributes(selAttrib, for: .selected)
}

呼叫来源:
您可以在 AppDelegate 中调用此方法

application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> >布尔

I am wondering why anyone have not mentioned about UIAppearanceProxy

Apple Doc::

https://developer.apple.com/documentation/uikit/uisegmentedcontrol#1653545

Sample Code:

    private class func applyUISegmentControlAppearance(){
    let apperance = UISegmentedControl.appearance()

    // Set Navigation bar Title colour
    let unselAttrib = [NSForegroundColorAttributeName:UIColor.yellow,
                                        NSFontAttributeName: UIFont.systemFont(ofSize: 15)]

    let selAttrib = [NSForegroundColorAttributeName:UIColor.red,
                     NSFontAttributeName: UIFont.boldSystemFont(ofSize: 15)]


    apperance.setTitleTextAttributes(unselAttrib, for: .normal)
    apperance.setTitleTextAttributes(selAttrib, for: .selected)
}

Call From:
You can call this method in AppDelegate from

application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool

猫瑾少女 2024-08-28 20:39:13

为了做你这样的事情,人们可能必须访问未记录的功能和黑客行为,这肯定会让苹果愤怒,并可能导致你的申请被拒绝。

现在,解决方案在于其他技巧,即您使用两个按钮,并在单击它们时交换它们的图像。保持按钮靠近和半分段控制的图像,以给出分段控制的错觉,这就是我可以建议您的全部内容。

希望这有帮助。

谢谢,

马杜普

For doing your kind of thing, one might have to access the undocumented features and hacks, which will certainly make apple furious, and that may lead to the rejection of your application.

Now, the solution lies in other trick that you use two buttons instead and have their images interchanged when they are clicked. Keep the buttons closer and images of half segmented control to give the illusion of segmented control and that is all I can suggest you.

Hope this helps.

Thanks,

Madhup

萌化 2024-08-28 20:39:13

您可以标记每个片段,然后设置 Tag 的 TintColor:

#define kTagOffState 0
#define kTagOnState  2

#define UIColorFromRGB(rgbValue) [UIColor \
        colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
        green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
        blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

//usage     UIColor color = UIColorFromRGB(0xF7F7F7);

 UIColor onColor = UIColorFromRGB(0xF7F7F7);
 UIColor offColor = UIColorFromRGB(0x878787);

        [multiStateControl setTag:kTagOffState forSegmentAtIndex:0];
        [multiStateControl setTag:kTagOnState forSegmentAtIndex:1];
        [multiStateControl setTintColor:onColor forTag:kTagOnState];
        [multiStateControl setTintColor:offColor forTag:kTagOffState];  

You can tag each of the segments, then set the TintColor forTag:

#define kTagOffState 0
#define kTagOnState  2

#define UIColorFromRGB(rgbValue) [UIColor \
        colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
        green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
        blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

//usage     UIColor color = UIColorFromRGB(0xF7F7F7);

 UIColor onColor = UIColorFromRGB(0xF7F7F7);
 UIColor offColor = UIColorFromRGB(0x878787);

        [multiStateControl setTag:kTagOffState forSegmentAtIndex:0];
        [multiStateControl setTag:kTagOnState forSegmentAtIndex:1];
        [multiStateControl setTintColor:onColor forTag:kTagOnState];
        [multiStateControl setTintColor:offColor forTag:kTagOffState];  
惯饮孤独 2024-08-28 20:39:13

我发现上面的答案非常有帮助。我正在使用分段控件来设置旋钮的精度。我综合了上面的答案并得出了这个:

-(void) viewDidLoad {

NSArray *segments = [NSArray arrayWithObjects:@"Course", @"Fine",nil];

[knob setPrecision:0.1]; // initial precision
// Set starting values

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segments];

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(120, 680, 228, 30);
[segmentedControl addTarget:self action:@selector(precisionSelect:) forControlEvents:UIControlEventValueChanged];
segmentedControl.momentary = YES;

[self.view addSubview:segmentedControl];
}   

- (void)precisionSelect:(UISegmentedControl*)sender
{   
    UIColor *tintcolor = [UIColor darkGrayColor];   
    if (sender.selectedSegmentIndex == 0) {
        [[sender.subviews objectAtIndex:0] setTintColor:nil];
        [[sender.subviews objectAtIndex:1] setTintColor:tintcolor];
    [knob setPrecision:0.1]; // Coarse
    } else {
        [[sender.subviews objectAtIndex:0] setTintColor:tintcolor];
        [[sender.subviews objectAtIndex:1] setTintColor:nil];
    [knob setPrecision:0.05]; // Fine
    }

}

希望这对其他人有帮助..
对我来说,关键是能够使用以下命令重置未选择的索引:setTintColor:nil];

I found the answers above very helpful. I am using the segmented control to set the precision of a knob. I took a hybrid of the answers above and came up with this:

-(void) viewDidLoad {

NSArray *segments = [NSArray arrayWithObjects:@"Course", @"Fine",nil];

[knob setPrecision:0.1]; // initial precision
// Set starting values

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segments];

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.frame = CGRectMake(120, 680, 228, 30);
[segmentedControl addTarget:self action:@selector(precisionSelect:) forControlEvents:UIControlEventValueChanged];
segmentedControl.momentary = YES;

[self.view addSubview:segmentedControl];
}   

- (void)precisionSelect:(UISegmentedControl*)sender
{   
    UIColor *tintcolor = [UIColor darkGrayColor];   
    if (sender.selectedSegmentIndex == 0) {
        [[sender.subviews objectAtIndex:0] setTintColor:nil];
        [[sender.subviews objectAtIndex:1] setTintColor:tintcolor];
    [knob setPrecision:0.1]; // Coarse
    } else {
        [[sender.subviews objectAtIndex:0] setTintColor:tintcolor];
        [[sender.subviews objectAtIndex:1] setTintColor:nil];
    [knob setPrecision:0.05]; // Fine
    }

}

Hope this helps others..
A key for me, was being able to reset the unselected index using: setTintColor:nil];

执笏见 2024-08-28 20:39:13
- (IBAction)segmentControlValueChanged:(UISegmentedControl *)sender
{
    if ([[sender.subviews firstObject] respondsToSelector:@selector(setTintColor:)]) {
        for (id segment in sender.subviews) {
            if ([segment respondsToSelector:@selector(isSelected)] && [segment isSelected]) {
                [segment setTintColor:[UIColor redColor]];
            } else {
                [segment setTintColor:[UIColor grayColor]];
            }
        }
    }
}
- (IBAction)segmentControlValueChanged:(UISegmentedControl *)sender
{
    if ([[sender.subviews firstObject] respondsToSelector:@selector(setTintColor:)]) {
        for (id segment in sender.subviews) {
            if ([segment respondsToSelector:@selector(isSelected)] && [segment isSelected]) {
                [segment setTintColor:[UIColor redColor]];
            } else {
                [segment setTintColor:[UIColor grayColor]];
            }
        }
    }
}
メ斷腸人バ 2024-08-28 20:39:13
Try this solution.    

输入图片此处描述

在此处输入图像描述

        @IBAction func dashBoardSegmentValueChanged(sender: AnyObject) {
            switch dashBoardSegment.selectedSegmentIndex
            {
            case 0:     
                sender.subviews.last?.backgroundColor = UIColor.whiteColor()
                sender.subviews.first?.backgroundColor =  UIColor.clearColor()

                break;
            case 1:            
                sender.subviews.first?.backgroundColor =  UIColor.whiteColor()
                sender.subviews.last?.backgroundColor = UIColor.clearColor()
                break;
            default:
                break;
            }
        }

Note: Make sure you select one segment subview as initial selected for easiness. It works if you have two segment subviews.
Try this solution.    

enter image description here

enter image description here

        @IBAction func dashBoardSegmentValueChanged(sender: AnyObject) {
            switch dashBoardSegment.selectedSegmentIndex
            {
            case 0:     
                sender.subviews.last?.backgroundColor = UIColor.whiteColor()
                sender.subviews.first?.backgroundColor =  UIColor.clearColor()

                break;
            case 1:            
                sender.subviews.first?.backgroundColor =  UIColor.whiteColor()
                sender.subviews.last?.backgroundColor = UIColor.clearColor()
                break;
            default:
                break;
            }
        }

Note: Make sure you select one segment subview as initial selected for easiness. It works if you have two segment subviews.
攒眉千度 2024-08-28 20:39:13
- (IBAction)segmentedControlValueChanged:(UISegmentedControl *)sender {
    for (int i = 0; i < sender.subviews.count; i++) {
        UIControl *component = [sender.subviews objectAtIndex:i];
        if ([component respondsToSelector:@selector(isSelected)]) {
            UIColor *selectedColor = [UIColor greenColor];
            UIColor *normalColor   = [UIColor blackColor];
            UIColor *tint = component.isSelected ? selectedColor : normalColor;
            [component setTintColor:tint];
        }
    }
}
- (IBAction)segmentedControlValueChanged:(UISegmentedControl *)sender {
    for (int i = 0; i < sender.subviews.count; i++) {
        UIControl *component = [sender.subviews objectAtIndex:i];
        if ([component respondsToSelector:@selector(isSelected)]) {
            UIColor *selectedColor = [UIColor greenColor];
            UIColor *normalColor   = [UIColor blackColor];
            UIColor *tint = component.isSelected ? selectedColor : normalColor;
            [component setTintColor:tint];
        }
    }
}
过潦 2024-08-28 20:39:13
[segmentedControl setSelectedSegmentTintColor:[UIColor darkGrayColor]];

//For iOS 13
[segmentedControl setSelectedSegmentTintColor:[UIColor darkGrayColor]];

//For iOS 13
故事与诗 2024-08-28 20:39:13

这个 Swift 4 代码对我有用

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)

This Swift 4 code works for me

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)
我不在是我 2024-08-28 20:39:12

这是将选定的段更改为任何 RGB 颜色的绝对最简单的方法。无需子类化或黑客攻击。

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

UIColor *newTintColor = [UIColor colorWithRed: 251/255.0 green:175/255.0 blue:93/255.0 alpha:1.0];
    segmentedControl.tintColor = newTintColor;

UIColor *newSelectedTintColor = [UIColor colorWithRed: 0/255.0 green:175/255.0 blue:0/255.0 alpha:1.0];
[[[segmentedControl subviews] objectAtIndex:0] setTintColor:newSelectedTintColor];

此示例显示了重要步骤:

  1. 将控件样式设置为
    “StyleBar”,这是必需的
    设置
  2. 未选择的颜色
    整个控件首先为橙色
  3. 设置所选内容的颜色
    线段变为绿色

注:

  • 步骤 1 和 2 可以在
    界面生成器,或代码为
    显示。然而步骤3只能完成
    在代码中
  • 设置的颜色值
    像这样的符号“123.0/255.0”是
    只是一种生成 RGB 值的方法
    脱颖而出,而不是标准化
    UIColor 所需的浮点值
    (如果你愿意就忽略它)

Here is the absolute simplest way to change the selected segment to any RGB color. No subclassing or hacks required.

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

UIColor *newTintColor = [UIColor colorWithRed: 251/255.0 green:175/255.0 blue:93/255.0 alpha:1.0];
    segmentedControl.tintColor = newTintColor;

UIColor *newSelectedTintColor = [UIColor colorWithRed: 0/255.0 green:175/255.0 blue:0/255.0 alpha:1.0];
[[[segmentedControl subviews] objectAtIndex:0] setTintColor:newSelectedTintColor];

This example shows the important steps:

  1. Sets the control style to
    "StyleBar", which is required for it
    to work
  2. Sets the un-selected color for the
    entire control first to orange
  3. Sets the color of the selected
    segment to green

Notes:

  • Steps 1 and 2 can be done in
    interface builder, or in code as
    shown. However step 3 can only be done
    in code
  • The color values being set with
    notation like this "123.0/255.0" is
    just a way to make the RGB values
    stand out instead the normalized
    float values required by UIColor
    (just ignore it if you like)
嘿看小鸭子会跑 2024-08-28 20:39:12

我发现在 UISegmentcontrol 发送者中为选定的段添加颜色的简单方法

是 UISegmentControl

for (int i=0; i<[sender.subviews count]; i++) 
{
    if ([[sender.subviews objectAtIndex:i]isSelected] ) 
    {               
    UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
    [[sender.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
   else 
    {
        [[sender.subviews objectAtIndex:i] setTintColor:nil];
    }
}

检查它对我有用

I found A Simple Way to Add Color for Selected Segment in UISegmentcontrol

sender is UISegmentControl

for (int i=0; i<[sender.subviews count]; i++) 
{
    if ([[sender.subviews objectAtIndex:i]isSelected] ) 
    {               
    UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
    [[sender.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
   else 
    {
        [[sender.subviews objectAtIndex:i] setTintColor:nil];
    }
}

Check its Working For Me

终遇你 2024-08-28 20:39:12

为此,您只需找到选定的段,例如通过迭代分段控件的子视图并测试 isSelected 属性,然后只需调用该段的 setTintColor: 方法即可子视图。

我通过将一个操作连接到 Interface Builder 中 ValueChanged 事件上的每个分段控件来完成此操作,我将它们连接到视图控制器文件中的此方法,这本质上是 msprague 的答案:

- (IBAction)segmentedControlValueChanged:(UISegmentedControl*)sender
{
    for (int i=0; i<[sender.subviews count]; i++)
    {
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[sender.subviews objectAtIndex:i]isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor whiteColor]];
        }
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[sender.subviews objectAtIndex:i] isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor blackColor]];
        }
    }
}

为了确保每次用户打开视图时,控件都会正确显示,我还必须重写 -(void)viewDidAppear:animated 方法并按如下方式调用该方法:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    //Ensure the segmented controls are properly highlighted
    [self segmentedControlValueChanged:segmentedControlOne];
    [self segmentedControlValueChanged:segmentedControlTwo];
}

如果您确实想要的话,可以获得一些奖励积分将分段控件设置为在选择时使用白色色调,那么您还需要在选择文本时将其颜色更改为黑色,您可以这样做:

//Create a dictionary to hold the new text attributes
NSMutableDictionary * textAttributes = [[NSMutableDictionary alloc] init];
//Add an entry to set the text to black
[textAttributes setObject:[UIColor blackColor] forKey:UITextAttributeTextColor];
//Set the attributes on the desired control but only for the selected state
[segmentedControlOne setTitleTextAttributes:textAttributes forState:UIControlStateSelected];

随着 iOS 6 的引入第一次在 viewDidAppear 方法中设置所选项目的色调颜色不起作用,为了解决这个问题,我使用中央调度在几分之一秒后更改所选颜色,如下所示:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self segmentedControlValueChanged:segmentedControlOne];
    });

To do this you simply have to find the selected segment, for example by iterating over the segmented control's subviews and testing the isSelected property, then simply call the setTintColor: method on that subview.

I did this by connecting an action to each segmented control on the ValueChanged event in Interface Builder, I connected them to this this method in the view controller file which is essentially msprague's answer:

- (IBAction)segmentedControlValueChanged:(UISegmentedControl*)sender
{
    for (int i=0; i<[sender.subviews count]; i++)
    {
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[sender.subviews objectAtIndex:i]isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor whiteColor]];
        }
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[sender.subviews objectAtIndex:i] isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor blackColor]];
        }
    }
}

To ensure that the control is displayed correctly each time the view is opened by the user I also had to override the -(void)viewDidAppear:animated method and call the method as follows:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    //Ensure the segmented controls are properly highlighted
    [self segmentedControlValueChanged:segmentedControlOne];
    [self segmentedControlValueChanged:segmentedControlTwo];
}

For some bonus points if you do want to set the segmented control to use a white tint color on selection then you will also want to change the color of the text to black when it's selected, you can do this like so:

//Create a dictionary to hold the new text attributes
NSMutableDictionary * textAttributes = [[NSMutableDictionary alloc] init];
//Add an entry to set the text to black
[textAttributes setObject:[UIColor blackColor] forKey:UITextAttributeTextColor];
//Set the attributes on the desired control but only for the selected state
[segmentedControlOne setTitleTextAttributes:textAttributes forState:UIControlStateSelected];

With the introduction of iOS 6 setting the tint color of the selected item for the first time in the viewDidAppear method wont work, to get around this I used grand central dispatch to change the selected color after a fraction of a second like so:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self segmentedControlValueChanged:segmentedControlOne];
    });
最丧也最甜 2024-08-28 20:39:12

由于某种原因,Apple 不允许您更改标准 UISegmentedControls 的颜色。

然而,有一种“合法”的方法可以解决这个问题,即将分段控件样式更改为 UISegmentedControlStyleBar。这使它看起来略有不同,您可能不喜欢,但它确实允许颜色。

    NSArray *itemArray = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];

//更改栏样式和广告以查看然后释放分段控制器

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor colorWithRed:.9 green:.1 blue:.1 alpha:1]; 
[self.view addSubview:segmentedControl];
[segmentedControl release];

希望这有帮助,

Seb Kade
“我是来帮忙的”

For some reason Apple dont allow you to change the color of standard UISegmentedControls.

There is however a "legal" way around it which is to change the segmented control style to UISegmentedControlStyleBar. This makes it look slightly different which you may not like but it does allow color.

    NSArray *itemArray = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];

//Change Bar Style and ad to view then release segmented controller

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor colorWithRed:.9 green:.1 blue:.1 alpha:1]; 
[self.view addSubview:segmentedControl];
[segmentedControl release];

Hope this helped,

Seb Kade
"I'm here to help"

梦境 2024-08-28 20:39:12

编辑:此解决方案不适用于 iOS 6。请参阅下面 David Thompson 的回答。

该线程确实很旧,但没有一个简单的答案对我来说合适。

只要您恢复取消选择的分段控件的颜色,接受的答案就有效。
像这样的东西将在您的值更改函数中起作用:

for (int i=0; i<[control.subviews count]; i++) 
{
    if ([[control.subviews objectAtIndex:i]isSelected] ) 
    {               
        UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    } else {
        UIColor *tintcolor=[UIColor grayColor]; // default color
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
}

Edit: This solution doesn't work on iOS 6. See David Thompson's answer below.

This thread is really old, but none of the simple answers worked properly for me.

The accepted answer works as long as you revert the color of the deselected segmented controls.
Something like this will work in your value changed function:

for (int i=0; i<[control.subviews count]; i++) 
{
    if ([[control.subviews objectAtIndex:i]isSelected] ) 
    {               
        UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    } else {
        UIColor *tintcolor=[UIColor grayColor]; // default color
        [[control.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
}
柠檬心 2024-08-28 20:39:12

我知道这是一个老问题但现在在 xcode 11 + 中,您可以设置选定的段色调颜色 在此处输入图像描述

在代码中我们可以使用 selectedSegmentTintColor。适用于 iOS 13+

I know this is an old question But now in xcode 11 +, you can set selected segment Tint colour enter image description here

In code us can use selectedSegmentTintColor. available iOS 13+

╰ゝ天使的微笑 2024-08-28 20:39:12

这是我对 uihacker 的 CustomSegmentedControl 的修改版本(请参阅评论中的信用)。我的想法是我改变了查找应该更改tintColor的子视图的方法,从使用selectedIndex到isSelected方法。因为我正在使用一个自定义 UISegmentedControl,它有 3 个或更多段,子视图顺序随机变化(即使 uihacker 的“hasSetSelectedIndexOnce”标志也不能解决这个问题!)。该代码仍处于早期开发阶段,因此使用它需要您自担风险。欢迎任何评论:)

另外,我添加了对界面生成器的支持,并覆盖 setSelectedSegmentIndex,以便它也更新颜色。享受!

CustomSegmentedControl.h

//
//  CustomSegmentedControl.h
//
//  Created by Hlung on 11/22/54 BE.
//  Copyright (c) 2554 __MyCompanyName__. All rights reserved.
//
//  Credit: http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

@interface CustomSegmentedControl : UISegmentedControl {
    UIColor *offColor,*onColor;
}
@property (nonatomic,retain) UIColor *offColor,*onColor;
-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor;
@end

CustomSegmentedControl.m

#import "CustomSegmentedControl.h"

@interface CustomSegmentedControl (private)
-(void)setInitialMode;
-(void)toggleHighlightColors;
@end

@implementation CustomSegmentedControl

@synthesize offColor,onColor;

-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor {
    if (self = [super initWithItems:items]) {
        // Initialization code
        self.offColor = offcolor;
        self.onColor = oncolor;
        [self setInitialMode];

        // default to 0, other values cause arbitrary highlighting bug
        [self setSelectedSegmentIndex:0];
    }
    return self;
}
- (void)awakeFromNib {
    // default colors
    self.offColor = [UIColor colorWithWhite:0.8 alpha:1];
    self.onColor = self.tintColor;
    [self setInitialMode];

    [self setSelectedSegmentIndex:0];
}

-(void)setInitialMode
{
    // set essential properties
    [self setBackgroundColor:[UIColor clearColor]];
    [self setSegmentedControlStyle:UISegmentedControlStyleBar];

    // loop through children and set initial tint
    for( int i = 0; i < [self.subviews count]; i++ )
    {
        [[self.subviews objectAtIndex:i] setTintColor:nil];
        [[self.subviews objectAtIndex:i] setTintColor:offColor];
    }

    // listen for updates, [self setSelectedSegmentIndex:0] triggers UIControlEventValueChanged in 5.0, 4.3 doesn't (facepalm), use  if( self.window ) to fix this
    [self addTarget:self action:@selector(toggleHighlightColors) forControlEvents:UIControlEventValueChanged];
}

// ---------------
// hlung's version
// ---------------
-(void)toggleHighlightColors
{
    // the subviews array order randomly changes all the time, change to check for "isSelected" instead
    for (id v in self.subviews) {
        if ([v isSelected]) [v setTintColor:onColor];
        else [v setTintColor:offColor];
    }
}
// override: update color when set selection
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
    [super setSelectedSegmentIndex:selectedSegmentIndex];
    [self toggleHighlightColors];
}
// ---------------
@end

Here is my modified version of uihacker's CustomSegmentedControl (see credit in comment). The idea is I change the way to find the subview that should have the tintColor changed, from using selectedIndex to isSelected method. Because I was working with a custom UISegmentedControl that has 3 or more segments which the subview ordering changes randomly (even uihacker's "hasSetSelectedIndexOnce" flag doesn't fix this!). The code is still in early dev stage so use it at your own risk. Any comment is welcomed :)

Also, I added support to interface builder, and override setSelectedSegmentIndex so that it also updates the color. Enjoy!

CustomSegmentedControl.h

//
//  CustomSegmentedControl.h
//
//  Created by Hlung on 11/22/54 BE.
//  Copyright (c) 2554 __MyCompanyName__. All rights reserved.
//
//  Credit: http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

@interface CustomSegmentedControl : UISegmentedControl {
    UIColor *offColor,*onColor;
}
@property (nonatomic,retain) UIColor *offColor,*onColor;
-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor;
@end

CustomSegmentedControl.m

#import "CustomSegmentedControl.h"

@interface CustomSegmentedControl (private)
-(void)setInitialMode;
-(void)toggleHighlightColors;
@end

@implementation CustomSegmentedControl

@synthesize offColor,onColor;

-(id)initWithItems:(NSArray *)items offColor:(UIColor*)offcolor onColor:(UIColor*)oncolor {
    if (self = [super initWithItems:items]) {
        // Initialization code
        self.offColor = offcolor;
        self.onColor = oncolor;
        [self setInitialMode];

        // default to 0, other values cause arbitrary highlighting bug
        [self setSelectedSegmentIndex:0];
    }
    return self;
}
- (void)awakeFromNib {
    // default colors
    self.offColor = [UIColor colorWithWhite:0.8 alpha:1];
    self.onColor = self.tintColor;
    [self setInitialMode];

    [self setSelectedSegmentIndex:0];
}

-(void)setInitialMode
{
    // set essential properties
    [self setBackgroundColor:[UIColor clearColor]];
    [self setSegmentedControlStyle:UISegmentedControlStyleBar];

    // loop through children and set initial tint
    for( int i = 0; i < [self.subviews count]; i++ )
    {
        [[self.subviews objectAtIndex:i] setTintColor:nil];
        [[self.subviews objectAtIndex:i] setTintColor:offColor];
    }

    // listen for updates, [self setSelectedSegmentIndex:0] triggers UIControlEventValueChanged in 5.0, 4.3 doesn't (facepalm), use  if( self.window ) to fix this
    [self addTarget:self action:@selector(toggleHighlightColors) forControlEvents:UIControlEventValueChanged];
}

// ---------------
// hlung's version
// ---------------
-(void)toggleHighlightColors
{
    // the subviews array order randomly changes all the time, change to check for "isSelected" instead
    for (id v in self.subviews) {
        if ([v isSelected]) [v setTintColor:onColor];
        else [v setTintColor:offColor];
    }
}
// override: update color when set selection
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex {
    [super setSelectedSegmentIndex:selectedSegmentIndex];
    [self toggleHighlightColors];
}
// ---------------
@end
唠甜嗑 2024-08-28 20:39:12

使用这个:

[[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected];

Use this:

[[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected];
小镇女孩 2024-08-28 20:39:12

不确定这是否会得到应用商店的批准,但我编写了一个 UISegmentedControl 的子类,它允许您设置自定义的选定和未选定颜色。查看注释以获取更多信息:

http://uihacker.blogspot .com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

Not sure if this will get approved by the app store, but I wrote a subclass to UISegmentedControl that lets you set a custom selected and unselected color. Check the notes for more info:

http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html

一个人练习一个人 2024-08-28 20:39:12

为了澄清 @jothikenpachi 上面提供的答案,我们发现以下 UISegmentController 类别在 iOS6 中运行良好,并且允许分段上的任意开/关颜色方案。另外,如果私有方法 isSelected/setTintColor: 在未来的操作系统版本中发生更改,它将正常失败。关于私有 API 调用的注意事项等。

@implementation UISegmentedControl(CustomTintExtension) {
-(void) updateCustomTintColorOn:(UIColor*)onColor Off:(UIColor*)offColor {
// Convenience function to rest the tint colors after selection, called upon change of selected index

SEL tint = @selector(setTintColor:);

for (UIView *view in [self subviews]) {
    // Loop through the views...
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:nil];
    }
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:offColor];
    }
}

// Checking if segment subview is selected...
SEL isSelected = @selector(isSelected);
for (UIView *view in [self subviews]) {
    if ([view respondsToSelector:isSelected] && [view performSelector:isSelected withObject:nil])
    {
        [view performSelector:tint withObject:onColor];
        break;
    }
}

}

请注意,此类别方法将从 UISegmentController 的 - (IBAction) segmentAction: (id)sender 方法中调用。

另请注意,对于 iOS6,您似乎可能需要首先在管理 UIViewController 的 - (void)viewDidAppear:(BOOL)animated 中调用此方法,这可能会导致动画闪烁。为了最大限度地减少这种情况,请尝试在 IB 中将“offColor”设置为 UISegmentController 的tintColor。

To clarify the answer provided above by @jothikenpachi we found the following UISegmentController category worked well in iOS6 and allows for an arbitrary on/off color scheme on segments. Plus it will fail gracefully if the private methods isSelected/setTintColor: are changed in future OS releases. Caveats around private API calls, etc.

@implementation UISegmentedControl(CustomTintExtension) {
-(void) updateCustomTintColorOn:(UIColor*)onColor Off:(UIColor*)offColor {
// Convenience function to rest the tint colors after selection, called upon change of selected index

SEL tint = @selector(setTintColor:);

for (UIView *view in [self subviews]) {
    // Loop through the views...
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:nil];
    }
    if (view && ([view respondsToSelector:tint])) {
        [view performSelector:tint withObject:offColor];
    }
}

// Checking if segment subview is selected...
SEL isSelected = @selector(isSelected);
for (UIView *view in [self subviews]) {
    if ([view respondsToSelector:isSelected] && [view performSelector:isSelected withObject:nil])
    {
        [view performSelector:tint withObject:onColor];
        break;
    }
}

}

Note, this category method would be called from within the UISegmentController's - (IBAction) segmentAction: (id)sender method.

Also note that with iOS6 it seems you may need to call this method initially in the governing UIViewController's - (void)viewDidAppear:(BOOL)animated which may result in a animation flash. To minimize this, try setting the "offColor" as the UISegmentController's tintColor in IB.

入怼 2024-08-28 20:39:12

我刚刚在 iOS 7 上遇到了这个问题,它的工作方式与 iOS6 不同。

在 iOS 7 中,所选段的标签颜色与 UISegementControl 背景颜色相同。在 iOS 7 上更改它的唯一方法是设置 UISegmentControl 的背景颜色。

segmentControl.backgroundColor = customColor;

I just ran into this issue on iOS 7, which works differently than iOS6.

In iOS 7, the color of the label for the selected segment is the same color as the UISegementControl background. The only way to change it on iOS 7 is to set the background color of the UISegmentControl.

segmentControl.backgroundColor = customColor;
时光磨忆 2024-08-28 20:39:12

我用了这个,它一步改变了所有颜色。

mySegmentedControl.tintColor = [UIColor redColor]

I used this and it changed all the colors in one step.

mySegmentedControl.tintColor = [UIColor redColor]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文