有什么方法可以自定义选定段的颜色UISegmentedControl
?
我找到了segmentedController.tintColor
属性,该属性使我可以自定义整个分段控件的颜色。问题是,当我为tintColor
属性选择鲜艳的颜色时,所选段几乎变得无法识别(其颜色与分段控件的其余部分几乎相同,因此很难区分所选段和未选中段)。因此,我无法使用任何良好的鲜艳颜色进行分段控制。解决方案是为选定的细分颜色提供一些单独的属性,但我找不到它。有人解决了吗?
有什么方法可以自定义选定段的颜色UISegmentedControl
?
我找到了segmentedController.tintColor
属性,该属性使我可以自定义整个分段控件的颜色。问题是,当我为tintColor
属性选择鲜艳的颜色时,所选段几乎变得无法识别(其颜色与分段控件的其余部分几乎相同,因此很难区分所选段和未选中段)。因此,我无法使用任何良好的鲜艳颜色进行分段控制。解决方案是为选定的细分颜色提供一些单独的属性,但我找不到它。有人解决了吗?
Answers:
我在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];
}
}
检查它为我工作
else [[sender.subviews objectAtIndex:i] setTintColor:sender.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];
此示例显示了重要步骤:
笔记:
为此,您只需找到选定的段即可,例如,通过遍历分段控件的子视图并测试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];
});
由于某些原因,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)“我在这里为您提供帮助”
编辑:此解决方案在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];
}
}
这是uihacker的CustomSegmentedControl的修改后的版本(请参见注释中的注释)。我的想法是,从使用selectedIndex到isSelected方法,我改变了查找应该更改tintColor的子视图的方式。因为我正在使用具有3个或更多段的自定义UISegmentedControl,其子视图顺序会随机更改(即使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
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex
您的电话viewDidLoad
:)
不知道这是否会得到应用商店的认可,但是我为UISegmentedControl编写了一个子类,可让您设置自定义的选定和未选定的颜色。查看说明以获取更多信息:
http://uihacker.blogspot.com/2010/05/iphone-uisegmentedcontrol-custom-colors.html
为了澄清@jothikenpachi上面提供的答案,我们发现以下UISegmentController类别在iOS6中运行良好,并允许在段上使用任意的开/关配色方案。另外,如果在将来的OS版本中更改了私有方法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。
我发现我可以在子视图上使用具有与分段相同索引的标签,以便以任何顺序将分段正确着色。
// 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];
}
}
}
在细分之间进行切换时,前两个解决方案对我不起作用。
我的解决方案是在视图控制器中处理段更改事件,然后每次更改段时都调用此方法:
+ (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];
}
}
我想知道为什么没有人提到 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
为了执行您的操作,可能必须访问未记录的功能和黑客,这肯定会让苹果大怒,并可能导致应用程序被拒绝。
现在,解决方案在于另一个技巧,您可以使用两个按钮来代替它们,并在单击它们时互换它们的图像。保持按钮靠近并保持半段控制的图像,以产生段控制的错觉,这就是我所建议的一切。
希望这可以帮助。
谢谢,
马杜普
您可以标记每个段,然后将TintColor设置为Tag:
#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]];
}
}
}
}
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.
- (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];
}
}
}
[segmentedControl setSelectedSegmentTintColor:[UIColor darkGrayColor]];
//For iOS 13
这个Swift 4代码对我有用
segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)