有没有办法自定义UISegmentedControl
中选定段的颜色?
我发现了segmentedController.tintColor
属性,它允许我自定义整个分段控件的颜色。
问题在于,当我为tintColor
属性选择明亮的颜色时,选定的段几乎无法被识别(它的颜色与其余分段控件的颜色几乎相同,因此很难区分选定和未选定的段)。
所以我不能使用任何好看的明亮颜色作为分段控制的颜色。
解决方案是一些单独的选定段颜色的属性,但我找不到这个属性。有人解决了这个问题吗?
有没有办法自定义UISegmentedControl
中选定段的颜色?
我发现了segmentedController.tintColor
属性,它允许我自定义整个分段控件的颜色。
问题在于,当我为tintColor
属性选择明亮的颜色时,选定的段几乎无法被识别(它的颜色与其余分段控件的颜色几乎相同,因此很难区分选定和未选定的段)。
所以我不能使用任何好看的明亮颜色作为分段控制的颜色。
解决方案是一些单独的选定段颜色的属性,但我找不到这个属性。有人解决了这个问题吗?
这是改变选中段到任何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];
这个示例展示了重要的步骤:
备注:
我找到了一种简单的方法,在UISegmentControl中为所选段添加颜色。
sender是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];
}
}
检查它对我是否有效
else [[sender.subviews objectAtIndex:i] setTintColor:sender.tintColor];
来重置旧的色调颜色。 - elimirksisSelected
属性,然后在该子视图上简单地调用setTintColor:
方法。- (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方法中设置所选项目的色调不起作用了,为了解决这个问题,我使用Grand Central Dispatch在过了几分之一秒后改变所选颜色:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self segmentedControlValueChanged:segmentedControlOne];
});
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];
编辑:此解决方案在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];
}
}
//
// 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
viewDidLoad
中调用- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex
:) - Hlung[[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]
为了澄清@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。