自定义UISegmentedControl的颜色

时间:2009-07-28 20:54:55

标签: iphone objective-c

有没有人知道如何根据UISegmentedControl自定义字符串的外观?我试图根据项目的选定状态设置单元格的背景颜色和文本颜色。

或者,你知道一种创建UIImages的方法,包括自定义字符串吗? (例如,创建具有白色背景的uiimage,覆盖文本,添加到分段控件)。

我知道您只能在分段控件中使用字符串或图像...

干杯!

12 个答案:

答案 0 :(得分:20)

UISegmentedControl有一个tintColor属性 - 这允许你改变控件的颜色,但不能改变一般的“样式”(圆角,斜面形状):

segmentedControl.tintColor = [UIColor blueColor];

至于动态创建UIImage,您可以创建一个CGContext,在该上下文中执行您需要的任何绘图(包括字符串),然后从上下文的CGImage中获取UIImage:

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

答案 1 :(得分:12)

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

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

答案 2 :(得分:9)

您所要做的就是:

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

答案 3 :(得分:9)

这里的大多数答案都没有回答如何基于所选状态设置按钮颜色的具体问题,这意味着对于未选择状态需要另一种颜色。我在这方面挣扎了很长时间,并希望与其他人分享我的解决方案。

我的示例使用包含三个细分的UISegmentedControl。所有三种颜色的未选择颜色应该相同,以使其具有统一的外观。第一个和最后一个段的选定状态具有唯一的颜色。

enter image description here

问题在于,不能保证分段控件的顺序相同,因此在您来回选择时颜色会混淆。 Dan发布了一个使用标签的解决方案,但不幸的是,它已不再适用于iOS 6及更高版本。

此代码大部分来自this post。我略微改变它以获得独特的选择颜色。

它的工作原理是排序,但请注意这两条重要的线条,用于设置所选颜色:

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's 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 :(得分:7)

我发现做这样的事情的最好方法是在分段控件上为不同的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];

答案 5 :(得分:2)

下面是一个适用于iOS9的示例代码,但它是一个hack,可能在以后的版本中不起作用:

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

答案 6 :(得分:2)

字体颜色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)

答案 7 :(得分:2)

从iOS13开始,您将不再能够修改细分控制器的色调颜色。如果必须自定义颜色,则需要使用selectedSegmentTintColor。     self.yourSegmentControl.selectedSegmentTintColor = UIColor(红色:240.0 / 255.0,绿色:183.0 / 255.0,蓝色:0.0 / 255.0,alpha:1.0)

答案 8 :(得分:1)

我能够通过XCode 6中的Interface Builder来实现。附件是色调属性:

enter image description here

答案 9 :(得分:1)

我想完成类似的事情 - 将所选片段的背景颜色设置为一种颜色,而其余片段的“轮廓”则是不同的颜色。

Portland Runner's answer大量借用,我们的想法是对UISegmentedControl进行子类化,并覆盖2个方法,既可以设置初始状态的样式,也可以捕获change事件,以便在用户选择不同的段时自动设置样式。

- (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 :(得分:0)

故事板解决方案

Xcode 11

选择控件,现在可以使用多种颜色选项。如果需要进一步完善,请查看“用户定义的运行时属性”。

image2

image1

答案 11 :(得分:0)

Swift 5.0

 if #available(iOS 13.0, *) {
     // For selected segment
      control.selectedSegmentTintColor = UIColor.red
 }

 // For control's background 
 control.layer.backgroundColor = UIColor.black.cgColor