Подтвердить что ты не робот

Настройка цветов UISegmentedControl

Кто-нибудь знает способ настроить внешний вид строки на основе UISegmentedControl? Я пытаюсь установить цвет фона ячейки и цвет текста по-разному в зависимости от выбранного состояния элемента.

В качестве альтернативы, вы знаете способ создания UIImages на лету, в который можно включать пользовательские строки? (например, создать UUImage с белым фоном, наложить текст, добавить в сегментированный элемент управления).

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

4b9b3361

Ответ 1

UISegmentedControl имеет свойство tintColor - это позволяет вам изменить цвет элемента управления, но не общий "стиль" (округленная, скошенная форма):

segmentedControl.tintColor = [UIColor blueColor];

Что касается создания UIImages на лету, вы можете создать CGContext, сделать любой чертеж, который вам нужен в этом контексте (включая строки), а затем получить UIImage из контекста CGImage:

CGContextRef drawContext = CGBitmapContextCreate(<many parameters>);
//do drawing here
CGImageRef finalImage = CGBitmapContextCreateImage(drawContext);
UIImage *cellImage = [UIImage finalImage];

Обратите внимание, что если вы используете код, подобный UIView.appearance().tintColor = .myColor (или эквивалент в ObjC), эффект, скорее всего, не произойдет.

Ответ 2

segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f  blue:0.61176f  alpha:1.0f];

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

Ответ 3

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

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

enter image description here

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

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

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

NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex;
[[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]];

- (void) updateSegmentColors
{
    UIColor *checkColor = [UIColor colorWithRed: 29/255.0 green:166/255.0 blue:47/255.0 alpha:1.0];
    NSArray *segmentColors = [[NSArray alloc] initWithObjects:checkColor, [UIColor blueColor], [UIColor redColor], nil];

    UISegmentedControl *betterSegmentedControl = self.StatusControl;

    // Get number of segments
    NSUInteger numSegments = [betterSegmentedControl.subviews count];

    // Reset segment color (non selected color)
    for( int i = 0; i < numSegments; i++ ) {
        // reset color
        [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:nil];
        [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:[UIColor blueColor]];
    }

    // Sort segments from left to right
    NSArray *sortedViews = [betterSegmentedControl.subviews sortedArrayUsingFunction:compareViewsByOrigin context:NULL];

    // Change color of selected segment
    NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex;
    [[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]];

    // Remove all original segments from the control
    for (id view in betterSegmentedControl.subviews) {
        [view removeFromSuperview];
    }

    // Append sorted and colored segments to the control
    for (id view in sortedViews) {
        [betterSegmentedControl addSubview:view];
    }
}


NSInteger static compareViewsByOrigin(id sp1, id sp2, void *context)
{
    // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects.
    float v1 = ((UIView *)sp1).frame.origin.x;
    float v2 = ((UIView *)sp2).frame.origin.x;
    if (v1 < v2)
        return NSOrderedAscending;
    else if (v1 > v2)
        return NSOrderedDescending;
    else
        return NSOrderedSame;
}

Я поместил код в свой собственный метод, потому что я загружаю эти сегментированные элементы управления в виде таблицы и должен запускать его при загрузке (существующие состояния из хранилища) и когда пользователь меняет выбор. Теперь мне просто нужно вызвать [Self updateSegmentColors];, когда что-то изменится.

Ответ 4

Все, что вам нужно сделать, это:

// Get an array of the subviews of a UISegmentedControl, for example myUISegmentedControl:

NSArray *arri = [myUISegmentedControl subviews];

// Change the tintColor of each subview within the array:

[[arri objectAtIndex:0] setTintColor:[UIColor redColor]];

[[arri objectAtIndex:1] setTintColor:[UIColor greenColor]];

Ответ 5

Лучшим способом, который я нашел для этого, является установка различных атрибутов для разных UIControlStates в сегментированном элементе управления.

self.segmentedControl.tintColor = [UIColor cb_Grey1Color];
self.segmentedControl.backgroundColor = [UIColor cb_Grey3Color];
NSDictionary *selectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName,
                                    [UIColor whiteColor], NSForegroundColorAttributeName,
                                    [UIColor cb_Grey1Color], NSBackgroundColorAttributeName, nil];
[self.segmentedControl setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];
NSDictionary *unselectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName,
                                      [UIColor cb_Grey2Color], NSForegroundColorAttributeName,
                                      [UIColor cb_Grey3Color], NSBackgroundColorAttributeName, nil];
[self.segmentedControl setTitleTextAttributes:unselectedAttributes forState:UIControlStateNormal];

Ответ 6

Вот пример кода, который работает с iOS9, но он взломан и может не работать в более поздних версиях:

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Title1", @"Title2"]];
for (id segment in [segmentedControl subviews])
{
    for (id view in [segment subviews])
    {
        NSString *desc = [view description];
        if ([desc containsString:@"UISegmentLabel"])
        {
            [segment setTintColor:([desc containsString:@"Title1"] ? [UIColor blueColor] : [UIColor greenColor])];
        }
    }
}

Ответ 7

Цвет шрифта swift 3 и swift 4, если вы хотите изменить

Для невыбранных

 segcntrl.setTitleTextAttributes(titleTextAttributes, for: .normal)

Для выбранного элемента

  segcntrl.setTitleTextAttributes(titleTextAttributes, for: .selected)



//MARK:- Segment color change
    self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: 
UIColor.white], for: UIControlState.selected)
    self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: 
UIColor.white], for: UIControlState.normal)

Ответ 8

Я смог сделать это через Interface Builder в XCode 6. Прикрепленное свойство tint:

enter image description here

Ответ 9

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

В значительной степени заимствуя из ответа Portland Runner, идея состоит в том, чтобы создать подкласс UISegmentedControl и переопределить 2 метода для стилизации исходного состояния, а также для захвата события изменения для его стилизации автоматически, когда пользователь выбирает различные сегменты.

- (void)layoutSubviews {
    [super layoutSubviews];
    [self updateSegmentColors];
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [self updateSegmentColors];
}
- (void)updateSegmentColors {
    NSArray* segments = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects.
        float v1 = ((UIView *)obj1).frame.origin.x;
        float v2 = ((UIView *)obj2).frame.origin.x;
        if (v1 < v2) return NSOrderedAscending;
        else if (v1 > v2) return NSOrderedDescending;
        else return NSOrderedSame;
    }];
    for (int i=0; i<segments.count; i++) {
        if (i == self.selectedSegmentIndex) {
            [segments[i] setTintColor:[UIColor redColor]];
        } else {
            [segments[i] setTintColor:[UIColor grayColor]];
        }
    }
}

Ответ 10

Начиная с iOS13, вы больше не сможете изменять цвет оттенка контроллера сегмента. Необходимо использовать selectedSegmentTintColor, если цвет должен быть настроен.   self.yourSegmentControl.selectedSegmentTintColor = UIColor (красный: 240,0/255,0, зеленый: 183,0/255,0, синий: 0,0/255,0, альфа: 1,0)

Ответ 11

Решение раскадровки

Xcode 11

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

image2

image1