How to change the colors of a segment in a UISegmentedControl in iOS 13?

前端 未结 14 887
醉话见心
醉话见心 2020-11-30 18:13

A UISegmentedControl has a new appearance in iOS 13 and existing code to alter the colors of the segmented control no longer work as they did.

Prior to

14条回答
  •  余生分开走
    2020-11-30 18:34

    Here is my take on Jonathan.'s answer for Xamarin.iOS (C#), but with fixes for image sizing. As with Cœur's comment on Colin Blake's answer, I made all images except the divider the size of the segmented control. The divider is 1xheight of the segment.

    public static UIImage ImageWithColor(UIColor color, CGSize size)
    {
        var rect = new CGRect(0, 0, size.Width, size.Height);
        UIGraphics.BeginImageContext(rect.Size);
        var context = UIGraphics.GetCurrentContext();
        context.SetFillColor(color.CGColor);
        context.FillRect(rect);
        var image = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();
        return image;
    }
    
    // https://stackoverflow.com/a/56465501/420175
    public static void ColorSegmentiOS13(UISegmentedControl uis, UIColor tintColor, UIColor textSelectedColor, UIColor textDeselectedColor)
    {
        if (!UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
        {
            return;
        }
    
        UIImage image(UIColor color)
        {
            return ImageWithColor(color, uis.Frame.Size);
        }
    
        UIImage imageDivider(UIColor color)
        {
            return ImageWithColor(color, 1, uis.Frame.Height);
        }
    
        // 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)
        uis.SetBackgroundImage(image(UIColor.Clear), UIControlState.Normal, UIBarMetrics.Default);
    
        // setBackgroundImage(tintColorImage, for: .selected, barMetrics: .default)
        uis.SetBackgroundImage(image(tintColor), UIControlState.Selected, UIBarMetrics.Default);
    
        // setBackgroundImage(UIImage(color: tintColor.withAlphaComponent(0.2)), for: .highlighted, barMetrics: .default)
        uis.SetBackgroundImage(image(tintColor.ColorWithAlpha(0.2f)), UIControlState.Highlighted, UIBarMetrics.Default);
    
        // setBackgroundImage(tintColorImage, for: [.highlighted, .selected], barMetrics: .default)
        uis.SetBackgroundImage(image(tintColor), UIControlState.Highlighted | UIControlState.Selected, UIBarMetrics.Default);
    
        // setTitleTextAttributes([.foregroundColor: tintColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
        // Change: support distinct color for selected/de-selected; keep original font
        uis.SetTitleTextAttributes(new UITextAttributes() { TextColor = textDeselectedColor }, UIControlState.Normal); //Font = UIFont.SystemFontOfSize(13, UIFontWeight.Regular)
        uis.SetTitleTextAttributes(new UITextAttributes() { TextColor = textSelectedColor, }, UIControlState.Selected); //Font = UIFont.SystemFontOfSize(13, UIFontWeight.Regular)
    
        // setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
        uis.SetDividerImage(imageDivider(tintColor), UIControlState.Normal, UIControlState.Normal, UIBarMetrics.Default);
    
        //layer.borderWidth = 1
        uis.Layer.BorderWidth = 1;
    
        //layer.borderColor = tintColor.cgColor
        uis.Layer.BorderColor = tintColor.CGColor;
    }
    

提交回复
热议问题