UISegmentedControl选中的分段颜色

73

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

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


理论上,此组件旨在防止此类情况发生。如果您选择背景颜色和色调颜色,则会为所选和未选中的内容交替显示。例如,如果您选择黑色背景和白色色调,则在选择其中一个时,它将以白色背景和黑色色调放置,反之亦然。 - jose920405
https://dev59.com/1lwZ5IYBdhLWcg3wROeN#55374590 - Lal Krishna
23个回答

2
我在iOS 7上遇到了这个问题,它与iOS 6不同。在iOS 7中,所选段的标签颜色与UISegementControl背景颜色相同。唯一改变它的方法是设置UISegmentControl的背景颜色。
segmentControl.backgroundColor = customColor;

2

1

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

苹果文档::

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) -> Bool


1

我发现可以使用与段相同索引的子视图上的标记,以便无论以任何顺序它们都能正确着色。

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

1

当我在不同的段之间切换时,前两个解决方案对我没有用。

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

+ (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];
    }    
}

0
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.

1
为什么要硬编码?这一切都可以通过Storyboard完成。 - OhadM
对于深入挖掘子视图并在那里更改backgroundColor的基本思路,我会点赞。虽然这是未记录的行为,但它为我提供了一个简单的解决方案,以控制各个段落的背景颜色。(Objective-C:sender.subviews [0] .backgroundColor) - Jeff

0
- (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];
        }
    }
}

0

我发现以上的答案非常有帮助。我正在使用分段控件来设置旋钮的精度。我综合了以上的答案,得出了以下代码:

-(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];


0
您可以为每个段落设置标签,然后为标签设置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];  

0

要做您这样的事情,可能需要访问未记录的功能和黑客技巧,这肯定会让苹果很生气,这可能会导致您的应用被拒绝。

现在,解决方案在于使用另一种技巧,您可以使用两个按钮,并在单击它们时交换它们的图像。将按钮放得更靠近,并使用半分段控件的图像来产生分段控件的幻觉,这是我能为您提供的全部建议。

希望这有所帮助。

谢谢,

Madhup


是的,谢谢。我猜如果你想要自定义颜色,使用看起来像分段控件的UIButtons是唯一的选择... - Mike
@Mike:我也这么认为。也许有人可以提出一些不是黑客方式并确实使用了文档化的API的解决方案。 - Madhup Singh Yadav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接