UISegmentedControlselect的段颜色

有没有什么办法可以在UISegmentedControl自定义所选段的颜色?

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

我发现了一个简单的方法来为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]; } } 

检查它为我工作

这是将所选段更改为任何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可以在界面构build器中完成,也可以在代码中完成。 但是第3步只能在代码中完成
  • 用这样的符号“123.0 / 255.0”设置的颜色值只是一种使RGB值突出的方法,而不是UIColor所要求的标准化的浮点值(如果你喜欢,就忽略它)

要做到这一点,你只需要find选定的片段,例如迭代分段控件的子视图并testingisSelected属性,然后调用该子视图上的setTintColor:方法。

我通过在Interface Builder中的ValueChanged事件上将每个分段控件连接到一个操作来实现这一点,我把它们连接到这个在view controller文件中的方法,这个方法本质上就是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]; } 

对于一些奖励点,如果您希望将分段控件设置为在select时使用白色色彩,那么在select文本时,还需要将文本的颜色更改为黑色,您可以这样做:

 //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方法中设置所选项目的色彩颜色将无法正常工作,为了解决这个问题,我使用了大中央调度(Grand central dispatch)在几分之一秒之后更改选定的颜色,如下所示:

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

出于某种原因,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“我来帮忙”

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

这个线程真的很老,但没有一个简单的答案适合我。

只要您恢复取消select的分段控件的颜色,接受的答案就可以工作。 像这样的东西将在你的价值改变的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]; } } 

这是我的修改版本的uihacker的CustomSegmentedControl(请参阅评论)。 这个想法是我改变的方式来find应该有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 

不知道这是否会得到app store的批准,但我写了一个UISegmentedControl的子类,让你设置一个自定义的select和未选中的颜色。 检查笔记以获取更多信息:

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

为了澄清@jothikenpachi提供的答案,我们发现以下UISegmentController类别在iOS6中运行良好,并允许在段上使用任意开/关颜色scheme。 另外,如果私有方法为Select / setTintColor:在将来的OS版本中更改,则它将优雅地失败。 私人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方法中- (IBAction) segmentAction: (id)sender

另外请注意,在iOS6中,您可能需要首先在pipe理UIViewController的- (void)viewDidAppear:(BOOL)animated中调用此方法,这可能会导致animationFlash。 为了尽量减less这种情况,尝试在IB中设置“offColor”作为UISegmentController的tintColor。

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

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

 segmentControl.backgroundColor = customColor; 

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

 mySegmentedControl.tintColor = [UIColor redColor] 

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

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

前两个解决scheme不适合我在段之间切换。

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

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

用这个:

 [[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected]; 
 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. 

为了做到这一点,可能需要访问无证的function和黑客,这肯定会让苹果大发雷霆,这可能会导致您的应用程序被拒绝。

现在,解决scheme在于另一个诀窍,即使用两个button来替代它们,并在点击时更改其图像。 保持button更接近和半分割控制的图像给分段控制的幻想,这是我可以build议你。

希望这可以帮助。

谢谢,

Madhup

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

我发现上面的答案非常有帮助。 我正在使用分段控制来设置旋钮的精度。 我采取了上述的答案杂交,并提出了这一点:

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

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