如何更改iOS 13中UISegmentedControl中段的颜色?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (4)
  • 关注 (0)
  • 查看 (6081)

A UISegmentedControl在iOS 13中具有新外观,并且用于改变分段控件颜色的现有代码不再像以前那样工作。

在iOS 13之前,您可以设置tintColor和将用于分段控件周围的边框,段之间的线以及所选段的背景颜色。然后,您可以使用前景色属性更改每个片段的标题颜色titleTextAttributes

在iOS 13下,tintColor什么都不做。您可以设置分段控件backgroundColor以更改分段控件的整体颜色。但我找不到任何方法来改变用作所选片段背景的颜色。设置文本属性仍然有效。我甚至尝试设置标题的背景颜色,但这只影响标题的背景,而不影响所选片段背景颜色的其余部分。

简而言之,如何修改UISegmentedControliOS 13中当前所选段的背景颜色?是否有适当的解决方案,使用公共API,不需要深入私有子视图结构?

iOS 13中没有新属性,UISegmentedControl或者UIControl没有任何相关的更改UIView

提问于
用户回答回答于

我尝试了解决方法,它对我很有用。这是Objective C版本:

@interface UISegmentedControl (Common)
- (void)ensureiOS12Style;
@end
@implementation UISegmentedControl (Common)
- (void)ensureiOS12Style {
    // UISegmentedControl has changed in iOS 13 and setting the tint
    // color now has no effect.
    if (@available(iOS 13, *)) {
        UIColor *tintColor = [self tintColor];
        UIImage *tintColorImage = [self imageWithColor:tintColor];
        // Must set the background image for normal to something (even clear) else the rest won't work
        [self setBackgroundImage:[self imageWithColor:self.backgroundColor ? self.backgroundColor : [UIColor clearColor]] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:tintColorImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:[self imageWithColor:[tintColor colorWithAlphaComponent:0.2]] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:tintColorImage forState:UIControlStateSelected|UIControlStateSelected barMetrics:UIBarMetricsDefault];
        [self setTitleTextAttributes:@{NSForegroundColorAttributeName: tintColor, NSFontAttributeName: [UIFont systemFontOfSize:13]} forState:UIControlStateNormal];
        [self setDividerImage:tintColorImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        self.layer.borderWidth = 1;
        self.layer.borderColor = [tintColor CGColor];
    }
}

- (UIImage *)imageWithColor: (UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}
@end
用户回答回答于

[self setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont boldSystemFontOfSize:14.0f]} forState:UIControlStateSelected];

加一句代码,完美解决问题,谢谢分享。

用户回答回答于

iOS 13中UISegmentedControl每个分段控件之间有个灰色竖线知道咋去掉吗

用户回答回答于

我无法为所选片段的颜色着色,希望它将在即将推出的测试版中修复。

如果不设置正常状态的背景图像(删除所有iOS 13样式),则设置所选状态的背景图像不起作用

但我能够让它恢复到iOS 12的外观(或者足够接近,我无法将角落半径恢复到更小的尺寸)。

它并不理想,但亮白色分段控件在我们的应用程序中看起来有点不合适。

(没有意识到UIImage(color:)我们的代码库中有一个扩展方法。但实现它的代码是在Web上)

extension UISegmentedControl {
    /// Tint color doesn't have any effect on iOS 13.
    func ensureiOS12Style() {
        if #available(iOS 13, *) {
            let tintColorImage = UIImage(color: tintColor)
            // Must set the background image for normal to something (even clear) else the rest won't work
            setBackgroundImage(UIImage(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
            setBackgroundImage(tintColorImage, for: .selected, barMetrics: .default)
            setBackgroundImage(UIImage(color: tintColor.withAlphaComponent(0.2)), for: .highlighted, barMetrics: .default)
            setBackgroundImage(tintColorImage, for: [.highlighted, .selected], barMetrics: .default)
            setTitleTextAttributes([.foregroundColor: tintColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
            setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
            layer.borderWidth = 1
            layer.borderColor = tintColor.cgColor
        }
    }
}

扫码关注云+社区

领取腾讯云代金券