26

有人知道自定义基于字符串的 UISegmentedControl 外观的方法吗?我正在尝试根据项目的选定状态来设置单元格的背景颜色和文本颜色。

或者,您是否知道一种即时创建包含自定义字符串的 UIImage 的方法?(例如,创建具有白色背景的 UUImage、覆盖文本、添加到分段控件)。

我知道你只能在分段控件中有字符串或图像......

4

12 回答 12

22

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

请注意,如果您使用类似UIView.appearance().tintColor = .myColor(或 ObjC 中的等价物)的代码,则效果很可能不会发生。

于 2009-07-29T00:38:04.900 回答
13
segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f  blue:0.61176f  alpha:1.0f];

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
于 2012-06-05T09:01:23.963 回答
11

这里的大多数答案都没有回答如何根据选定状态设置按钮颜色的具体问题,这意味着未选定状态需要另一种颜色。我为此苦苦挣扎了很长一段时间,并想分享我的解决方案供其他人使用。

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

在此处输入图像描述

问题是分段控件不能保证顺序相同,因此在您来回选择时颜色会混淆。Dan 发布了一个使用标签的解决方案,但不幸的是,它不再保证适用于 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'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];在事情发生变化时打电话。

于 2014-07-12T05:06:31.083 回答
10

你所要做的就是:

// 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]];
于 2012-09-17T06:55:56.570 回答
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];
于 2015-07-03T13:45:30.847 回答
3

从 iOS13 开始,您将无法再修改段控制器的色调颜色。selectedSegmentTintColor如果必须定制颜色,则需要使用。

self.yourSegmentControl.selectedSegmentTintColor = UIColor(red: 240.0/255.0, green: 183.0/255.0, blue: 0.0/255.0, alpha: 1.0)
于 2019-08-14T10:53:10.917 回答
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])];
        }
    }
}
于 2016-01-22T01:25:15.170 回答
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)
于 2018-02-07T13:12:35.027 回答
1

我可以通过 XCode 6 中的 Interface Builder 做到这一点。附加的是 tint 属性:

在此处输入图像描述

于 2015-03-26T01:46:10.790 回答
1

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

大量借鉴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]];
        }
    }
}
于 2017-10-30T14:57:26.970 回答
0

斯威夫特 5.0

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

 // For control's background 
 control.layer.backgroundColor = UIColor.black.cgColor
于 2020-07-21T21:44:36.890 回答
-1

故事板解决方案

Xcode 11

选择控件,现在可以使用多种颜色选项。如果您需要进一步细化 - 查看用户定义的运行时属性。

图2

图像1

于 2019-09-23T22:19:15.933 回答