Cor do segmento selecionado UISegmentedControl

Existe alguma maneira de personalizar a cor do segmento selecionado no UISegmentedControl ?

Eu encontrei a propriedade segmentedController.tintColor , que me permite personalizar a cor de todo o controle segmentado. O problema é que, quando seleciono colors shinys para a propriedade tintColor , o segmento selecionado se torna quase irreconhecível (sua cor é quase igual ao restante do controle segmentado, portanto é difícil distinguir segmentos selecionados e não selecionados). Portanto, não posso usar colors boas e shinys para controle segmentado. A solução seria uma propriedade separada para a cor de segmento selecionada, mas não consigo encontrá-la. Alguém resolveu isso?

Eu encontrei uma maneira simples de adicionar cor para o segmento selecionado no UISegmentcontrol

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

Verifique o seu trabalho para mim

Aqui está a maneira mais simples de alterar o segmento selecionado para qualquer cor RGB. Nenhuma subsorting ou hacks são necessários.

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

Este exemplo mostra os passos importantes:

  1. Define o estilo de controle para “StyleBar”, que é necessário para que funcione
  2. Define a cor não selecionada para todo o controle primeiro para laranja
  3. Define a cor do segmento selecionado para verde

Notas:

  • As etapas 1 e 2 podem ser feitas no construtor de interface ou no código, conforme mostrado. No entanto, o passo 3 só pode ser feito em código
  • Os valores de cor que estão sendo definidos com notação como “123.0 / 255.0” é apenas uma maneira de destacar os valores RGB em vez dos valores de flutuação normalizados exigidos pelo UIColor (apenas ignore-o se desejar)

Para fazer isso, basta localizar o segmento selecionado, por exemplo, iterando sobre as isSelected do controle segmentado e testando a propriedade isSelected ; em seguida, simplesmente chame o método setTintColor: nessa subvisão.

Eu fiz isso conectando uma ação a cada controle segmentado no evento ValueChanged no Interface Builder, conectei-os a este método no arquivo do controlador de visualização que é essencialmente a resposta do 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]]; } } } 

Para garantir que o controle seja exibido corretamente toda vez que a visualização é aberta pelo usuário, também tive que replace o método de -(void)viewDidAppear:animated e chamar o método da seguinte maneira:

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; //Ensure the segmented controls are properly highlighted [self segmentedControlValueChanged:segmentedControlOne]; [self segmentedControlValueChanged:segmentedControlTwo]; } 

Para alguns pontos de bônus, se você quiser definir o controle segmentado para usar uma cor de matiz branca na seleção, você também desejará alterar a cor do texto para preto quando estiver selecionado, assim:

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

Com a introdução do iOS 6, definir a cor do tom do item selecionado pela primeira vez no método viewDidAppear não funciona, para contornar isso, usei o despacho central para alterar a cor selecionada após uma fração de segundo da seguinte forma:

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

Por algum motivo, a Apple não permite que você altere a cor dos UISegmentedControls padrão.

Há, no entanto, uma maneira “legal” em torno dele, que é alterar o estilo de controle segmentado para UISegmentedControlStyleBar. Isso faz com que pareça um pouco diferente do que você pode não gostar, mas permite colors.

  NSArray *itemArray = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil]; UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray]; 

// Alterar o estilo da barra e o anúncio para visualizar e, em seguida, liberar o controlador segmentado

 segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; segmentedControl.tintColor = [UIColor colorWithRed:.9 green:.1 blue:.1 alpha:1]; [self.view addSubview:segmentedControl]; [segmentedControl release]; 

Espero que isso tenha ajudado

Seb Kade “Estou aqui para ajudar”

Edit : Esta solução não funciona no iOS 6. Veja a resposta de David Thompson abaixo.

Este tópico é realmente antigo, mas nenhuma das respostas simples funcionou corretamente para mim.

A resposta aceita funciona desde que você reverta a cor dos controles segmentados não selecionados. Algo parecido com isso funcionará na sua function de alteração de valor:

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

Aqui está a minha versão modificada do CustomSegmentedControl do uihacker (veja o crédito no comentário). A idéia é que eu mude a maneira de encontrar a subvisualização que deve ter o tintColor alterado, desde o uso do selectedIndex até o método isSelected. Porque eu estava trabalhando com um UISegmentedControl personalizado que tem 3 ou mais segmentos que a ordem de subvisualização muda aleatoriamente (até mesmo o sinalizador “hasSetSelectedIndexOnce” do uihacker não corrige isso!). O código ainda está no estágio inicial do dev para usá-lo por sua conta e risco. Qualquer comentário é bem-vindo 🙂

Além disso, adicionei suporte ao construtor de interface e substituo setSelectedSegmentIndex para que ele também atualize a cor. Apreciar!

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 

Não tenho certeza se isso será aprovado pela loja de aplicativos, mas eu escrevi uma subclass para UISegmentedControl que permite definir uma cor personalizada selecionada e não selecionada. Verifique as notas para mais informações:

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

Para esclarecer a resposta fornecida acima por @jothikenpachi, descobrimos que a categoria UISegmentController a seguir funcionou bem no iOS6 e permite um esquema de colors on / off arbitrário nos segmentos. Além disso, ele falhará normalmente se os methods privados foremSelected / setTintColor: forem alterados em versões futuras do SO. Advertências sobre chamadas de API privadas, etc.

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

Observe que esse método de categoria seria chamado a partir do método do emissor UISegmentController - (IBAction) segmentAction: (id)sender .

Observe também que com o iOS6 parece que você pode precisar chamar este método inicialmente no UIViewController - (void)viewDidAppear:(BOOL)animated que pode resultar em um flash de animação. Para minimizar isso, tente definir o “offColor” como tintColor do UISegmentController no IB.

Acabei de me deparar com este problema no iOS 7, que funciona de forma diferente do iOS6.

No iOS 7, a cor do label do segmento selecionado é da mesma cor do segundo plano do UISegementControl. A única maneira de alterá-lo no iOS 7 é definir a cor de fundo do UISegmentControl.

 segmentControl.backgroundColor = customColor; 

Eu usei isso e mudou todas as colors em um passo.

 mySegmentedControl.tintColor = [UIColor redColor] 

Descobri que poderia usar a tag nas subvisualizações com o mesmo índice dos segmentos, para que, em qualquer ordem, os segmentos sejam coloridos corretamente.

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

As duas principais soluções não funcionaram comigo ao alternar entre segmentos.

Minha solução foi manipular o evento de alteração de segmento no meu controlador de visualização e, em seguida, chamar esse método sempre que o segmento for alterado:

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

Usa isto:

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

Para fazer o seu tipo de coisa, pode-se ter que acessar os resources não documentados e hacks, o que certamente tornará a apple furiosa, e isso pode levar à rejeição do seu aplicativo.

Agora, a solução está em outro truque que você usa dois botões e tem suas imagens trocadas quando são clicadas. Mantenha os botões mais perto e imagens de controle segmentado para dar a ilusão de controle segmentado e isso é tudo que posso sugerir a você.

Espero que isto ajude.

Obrigado,

Madhup

Você pode marcar cada um dos segmentos e, em seguida, definir o 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]; 

Eu achei as respostas acima muito úteis. Eu estou usando o controle segmentado para definir a precisão de um botão. Eu peguei um híbrido das respostas acima e descobri isso:

 -(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 } } 

Espero que isso ajude os outros .. Uma chave para mim, foi a possibilidade de redefinir o índice não selecionado usando: 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. 

insira a descrição da imagem aqui

insira a descrição da imagem aqui

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

Eu estou querendo saber por que alguém não mencionou sobre UIAppearanceProxy

Apple Doc ::

https://developer.apple.com/documentation/uikit/uisegmentedcontrol#1653545

Código de amostra:

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

Call From: Você pode chamar esse método em AppDelegate de

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

Este código Swift 4 funciona para mim

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