UISegmentedControl цвет выбранного сегмента

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

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

67 голосов | спросил Mike 16 FebruaryEurope/MoscowbTue, 16 Feb 2010 06:56:45 +0300000000amTue, 16 Feb 2010 06:56:45 +030010 2010, 06:56:45

21 ответ


0

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

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

ответил jothikenpachi 8 FebruaryEurope/MoscowbWed, 08 Feb 2012 10:40:59 +0400000000amWed, 08 Feb 2012 10:40:59 +040012 2012, 10:40:59
0

Вот самый простой способ изменить выбранный сегмент на любой цвет 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 (просто игнорируйте его, если хотите)
ответил whitneyland 9 Mayam11 2011, 08:30:50
0

Чтобы сделать это, вам просто нужно найти выбранный сегмент, например, перебирая подвиды сегментированного элемента управления и проверяя свойство 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];
    });
ответил David Thompson 24 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 24 Sep 2012 12:02:17 +0400 2012, 12:02:17
0

По какой-то причине 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 30 MarpmTue, 30 Mar 2010 15:38:30 +04002010-03-30T15:38:30+04:0003 2010, 15:38:30
0

Изменить . Это решение не работает на 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];
    }
}
ответил Mike Sprague 25 Maypm12 2012, 21:29:20
0

Вот моя модифицированная версия 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
ответил Hlung 22 22011vEurope/Moscow11bEurope/MoscowTue, 22 Nov 2011 13:50:33 +0400 2011, 13:50:33
0

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

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

ответил cacheflowe 28 Mayam10 2010, 03:30:08
0

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

ответил MoFlo 2 +04002012-10-02T07:59:27+04:00312012bEurope/MoscowTue, 02 Oct 2012 07:59:27 +0400 2012, 07:59:27
0

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

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

segmentControl.backgroundColor = customColor;
ответил Barlow Tucker 7 Jam1000000amTue, 07 Jan 2014 01:52:32 +040014 2014, 01:52:32
0

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

mySegmentedControl.tintColor = [UIColor redColor]
ответил smDeveloper 21 Jpm1000000pmWed, 21 Jan 2015 22:28:17 +030015 2015, 22:28:17
0

Я обнаружил, что могу использовать тег для подпредставлений с тем же индексом, что и у сегментов, так что в любом порядке они будут окрашены правильно.

// 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];
        }
    }
}
ответил RexMac66 5 MaramMon, 05 Mar 2012 06:47:51 +04002012-03-05T06:47:51+04:0006 2012, 06:47:51
0

Два лучших решения не помогли мне при переключении между сегментами.

Мое решение состояло в том, чтобы обработать событие изменения сегмента в моем контроллере представления и затем вызывать этот метод каждый раз, когда сегмент изменяется:

+ (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];
    }    
}
ответил Brandon O'Rourke 28 J000000Saturday12 2012, 00:07:55
0

Используйте это:

[[UISegmentedControl appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:255.0/255 green:37.0/255 blue:99.0/255 alpha:1.0]} forState:UIControlStateSelected];
ответил user3272090 18 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 18 Sep 2014 10:28:42 +0400 2014, 10:28:42
0
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.
ответил A.G 6 Jam1000000amWed, 06 Jan 2016 08:40:48 +030016 2016, 08:40:48
0

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

Теперь решение заключается в другом трюке, который заключается в том, что вместо двух кнопок вы меняете их изображения при нажатии. Держите кнопки ближе и изображения полусегментированного контроля, чтобы создать иллюзию сегментированного контроля, и это все, что я могу вам предложить.

Надеюсь, это поможет.

Спасибо,

Madhup

ответил Madhup Singh Yadav 16 FebruaryEurope/MoscowbTue, 16 Feb 2010 07:25:22 +0300000000amTue, 16 Feb 2010 07:25:22 +030010 2010, 07:25:22
0

Вы можете пометить каждый сегмент, а затем установить TintColor для тега:

#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];  
ответил scooter133 28 FebruaryEurope/MoscowbTue, 28 Feb 2012 22:09:45 +0400000000pmTue, 28 Feb 2012 22:09:45 +040012 2012, 22:09:45
0

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

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

ответил David DelMonte 11 PM00000030000005031 2012, 15:47:50
0
- (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]];
            }
        }
    }
}
ответил 1mperial 18 PM00000010000001131 2015, 13:25:11
0
- (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];
        }
    }
}
ответил Ted 24 AM000000100000004731 2016, 10:47:47
0

Мне интересно, почему никто не упомянул о UIAppearanceProxy

Apple Doc ::

  

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

ответил thesummersign 1 MarpmThu, 01 Mar 2018 18:47:08 +03002018-03-01T18:47:08+03:0006 2018, 18:47:08
0

Этот код Swift 4 работает для меня

segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected)
ответил ayalcinkaya 6 J0000006Europe/Moscow 2018, 17:29:18

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132