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

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

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

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

    Проверьте его работу для меня

    Вот самый простой способ изменить выбранный сегмент на любой цвет RGB. Никаких подclassов или взломов не требуется.

     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 выделялись вместо нормализованных значений float, требуемых UIColor (просто игнорируйте его, если хотите)

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

    Я сделал это, подключив действие к каждому сегментированному элементу управления событием ValueChanged в Interface Builder, я связал их с этим этим методом в файле controllerа вида, который по существу является ответом 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: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]; 

    // Измените стиль и объявление в панели объявлений, затем отпустите сегментированный controller

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

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

    Seb Kade «Я здесь, чтобы помочь»

    Изменить : это решение не работает на 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]; } } 

    Вот моя измененная версия CustomSegmentedControl uihacker (см. Комментарий в комментарии). Идея заключается в том, что я изменяю способ поиска subview, который должен иметь изменение tintColor, с использованием метода selectedIndex to isSelected. Поскольку я работал с настраиваемым UISegmentedControl, у которого есть 3 или более сегментов, которые упорядочиваются подзаголовками, беспорядочно (даже флаг «hasSetSelectedIndexOnce» 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 

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

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

    Чтобы пояснить ответ, приведенный выше, @jothikenpachi, мы обнаружили, что следующая категория UISegmentController хорошо работала в iOS6 и допускает произвольную цветовую схему включения / выключения на сегментах. Плюс это будет неудачно изящно, если частные методы areSelected / 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 - (IBAction) segmentAction: (id)sender .

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

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

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

     segmentControl.backgroundColor = customColor; 

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

     mySegmentedControl.tintColor = [UIColor redColor] 

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

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

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

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

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

    Использовать это:

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

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

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

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

    Благодаря,

    Madhup

    Вы можете пометить каждый из сегментов, а затем установить 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]; 

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

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

    Мне интересно, почему никто не упомянул о 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

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

     segmentedControl.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.red], for: .selected) 
    Давайте будем гением компьютера.