控制选定的片段颜色

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

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

98360 次浏览

对于您这种类型的事情,您可能不得不访问未记录的特性和黑客,这肯定会让苹果愤怒,并可能导致您的应用程序被拒绝。

现在,解决方案在于使用两个按钮来代替,并在点击图像时进行图像交换。保持按钮更紧密和半分段控制的图像给分段控制的错觉,这就是我能建议你。

希望这个能帮上忙。

谢谢,

Madhup

由于某些原因,苹果不允许你改变标准 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 “我是来帮忙的”

不确定这是否会得到应用程序商店的批准,但我写了一个子类 UISegmentedControl,让您设置自定义选择和未选择的颜色。更多信息请查看笔记:

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

这是将 选定的片段改变为任意 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可以在 Interface Builder 或代码 然而,第3步只能完成 用密码
  • 设置的颜色值 像“123.0/255.0”这样的符号是 只是一种方法,使 RGB 值 站出来,而不是正常化 UIColor 要求的 float 值 (如果你喜欢就忽略它)

这里是我修改过的 uhacker 的 CustomSegmentedControl 版本(见注释中的信息)。其思想是我改变了查找应该更改 tintColor 的子视图的方法,从使用 selectedIndex 改为使用 isSelected 方法。因为我使用的是一个定制的 UISegmentedControl,它有3个或更多的片段,子视图的排序会随机改变(甚至 uhacker 的“ hasSetSelectedIndexOnce”标志也不能修复这个问题!).该代码仍处于早期开发阶段,因此使用它的风险由您自己承担。欢迎任何评论:)

此外,我还增加了对 Interface Builder 的支持,并覆盖 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

我发现了一个简单的方法来添加颜色的选定段在 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];
}
}

检查它为我工作

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

我发现我可以在子视图上使用标记,其索引与段落相同,这样不管它们的顺序如何,段落都会被正确地着色。

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

编辑 : 这个解决方案在 iOS6上不起作用。

这个帖子真的很老了,但是没有一个简单的答案对我有效。

只要您还原取消选定的分段控件的颜色,接受的答案就可以工作。 类似这样的东西会在你的价值转换函数中起作用:

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

前两个解决方案对我来说并不适合在不同部分之间切换。

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

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

我发现上面的答案很有帮助。我使用分段控制来设置旋钮的精度。我把上面的答案混合在一起,得出了这样的结论:

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

要做到这一点,您只需要找到选定的段,例如通过迭代分段控件的子视图和测试 isSelected属性,然后简单地调用该子视图上的 setTintColor:方法。

我通过将一个操作连接到 ValueChanged 事件中的每个分段控件来完成这个 Interface Builder,我将它们连接到视图控制器文件中的这个方法,这实际上就是 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];

随着 IOS6第一次在 viewDidAppear 方法中设置所选项目的色彩的介绍,为了避免这个问题,我使用了 grand central send 在一秒钟之后改变所选颜色,如下所示:

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

为了澄清上面@jothikenpachi 提供的答案,我们发现下面的 UISegmentController 类别在 iOS6中工作得很好,并且允许在段上使用任意的开/关颜色方案。另外,如果私有方法 selected/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。

我刚刚在 iOS7上遇到了这个问题,它的工作原理与 iOS6不同。

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

segmentControl.backgroundColor = customColor;

用这个:

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

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

mySegmentedControl.tintColor = [UIColor redColor]
- (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]];
}
}
}
}
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.
- (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];
}
}
}

我想知道为什么没有人提到 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)
}

电话: 中调用此方法

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

这个 Swift 4代码对我有用

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


//For iOS 13

我知道这是一个老问题,但现在在 xcode 11 + ,你可以设置选定的段色彩enter image description here

在代码中我们可以使用 selectedSegmentTintColor。可用的 iOS13 +