UISegmentedControl цвет выбранного сегмента - PullRequest
67 голосов
/ 16 февраля 2010

Есть ли способ настроить цвет выбранного сегмента в UISegmentedControl?

Я обнаружил свойство segmentedController.tintColor, которое позволяет мне настраивать цвет всего сегментированного элемента управления.Проблема в том, что когда я выбираю яркий цвет для свойства tintColor, выделенный сегмент становится практически неузнаваемым (его цвет почти такой же, как и у остального сегментированного элемента управления, поэтому трудно различить выбранные и невыбранные сегменты).Поэтому я не могу использовать какие-либо хорошие яркие цвета для сегментированного контроля.Решением было бы отдельное свойство для выбранного цвета сегмента, но я не могу его найти.Кто-нибудь решил это?

Ответы [ 21 ]

74 голосов
/ 09 мая 2011

Вот самый простой способ изменить выбранный сегмент на любой цвет 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 можно выполнить в построитель интерфейса, или в коде как показано на рисунке. Однако шаг 3 можно сделать только в коде
  • Значения цвета устанавливаются с обозначение как это "123.0 / 255.0" является просто способ сделать значения RGB выделяться вместо нормализованного значения с плавающей запятой, требуемые UIColor (просто игнорируйте, если хотите)
52 голосов
/ 08 февраля 2012

Я нашел простой способ добавить цвет для выбранного сегмента в 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];
    }
}

Проверьте, работает ли он для меня

22 голосов
/ 24 сентября 2012

Чтобы сделать это, вам просто нужно найти выбранный сегмент, например, путем итерации по подпредставлениям сегментированного элемента управления и проверки свойства isSelected, а затем просто вызвать метод setTintColor: для этого подпредставления.

Я сделал это, подключив действие к каждому сегментированному элементу управления в событии 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];
    });
9 голосов
/ 30 марта 2010

По какой-то причине 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];

Надеюсь, это помогло,

Себ Каде «Я здесь, чтобы помочь»

8 голосов
/ 25 мая 2012

Редактировать : Это решение не работает на iOS 6. См. Ответ Дэвида Томпсона ниже.

Эта ветка действительно старая, но ни один из простых ответов для меня не сработал.

Принятый ответ работает до тех пор, пока вы не измените цвет отмененных выделенных сегментированных элементов управления. Примерно так будет работать в вашей функции измененного значения:

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];
    }
}
6 голосов
/ 22 ноября 2011

Вот моя модифицированная версия CustomSegmentedControl uihacker (см. Комментарий в комментариях).Идея состоит в том, чтобы изменить способ поиска подпредставления, для которого должен быть изменен tintColor, с использования selectedIndex на метод isSelected.Потому что я работал с пользовательским UISegmentedControl, который имеет 3 или более сегмента, порядок упорядочивания которых изменяется случайным образом (даже флаг hasSetlectedIndexOnce uihacker не может это исправить!)Код все еще находится на ранней стадии разработки, поэтому используйте его на свой страх и риск.Приветствуется любой комментарий:)

Кроме того, я добавил поддержку построителя интерфейса и переопределил 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
2 голосов
/ 07 января 2014

Я только что столкнулся с этой проблемой на iOS 7, которая работает иначе, чем на iOS6.

В iOS 7 цвет метки для выбранного сегмента совпадает с цветом фона UISegementControl. Единственный способ изменить это на iOS 7 - установить цвет фона UISegmentControl.

segmentControl.backgroundColor = customColor;
2 голосов
/ 02 октября 2012

Чтобы прояснить ответ, предоставленный выше @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;
    }
}

}

Обратите внимание, этот метод категории будет вызываться из метода - (IBAction) segmentAction: (id)sender UISegmentController.

Также обратите внимание, что в iOS6 может потребоваться первоначально вызвать этот метод в управляющем UIViewController - (void)viewDidAppear:(BOOL)animated, что может привести к флэш-анимации. Чтобы свести к минимуму это, попробуйте установить "offColor" в качестве tintColor UISegmentController в IB.

2 голосов
/ 21 января 2015

Я использовал это, и он изменил все цвета за один шаг.

mySegmentedControl.tintColor = [UIColor redColor]
2 голосов
/ 28 мая 2010

Не уверен, будет ли это одобрено магазином приложений, но я написал подкласс для UISegmentedControl, который позволяет вам устанавливать выбранный и невыбранный цвет. Проверьте заметки для получения дополнительной информации:

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

...