IOS 13 में UISegmentedControl में एक सेगमेंट के रंग कैसे बदलें?


109

एक UISegmentedControlआईओएस 13 में एक नया स्वरूप है और मौजूदा कोड हिस्सों में बंटा हुआ नियंत्रण के रंग अब काम को बदलने के लिए के रूप में वे किया था।

IOS 13 से पहले आप इसे निर्धारित कर सकते हैं tintColorऔर इसका इस्तेमाल खंडों के नियंत्रण, खंडों के बीच की रेखाओं और चयनित खंड की पृष्ठभूमि के रंग के चारों ओर सीमा के लिए किया जाएगा। तब आप अग्रभूमि रंग विशेषता का उपयोग करके प्रत्येक खंड के शीर्षकों का रंग बदल सकते थे titleTextAttributes

IOS 13 के तहत, tintColorकुछ नहीं करता है। आप खंडित नियंत्रण के backgroundColorसमग्र रंग को बदलने के लिए खंडित नियंत्रण सेट कर सकते हैं । लेकिन मुझे चयनित खंड की पृष्ठभूमि के रूप में उपयोग किए गए रंग को बदलने का कोई तरीका नहीं मिल सकता है। पाठ विशेषताएँ सेट करना अभी भी काम करता है। मैंने शीर्षक की पृष्ठभूमि का रंग निर्धारित करने की भी कोशिश की, लेकिन यह केवल शीर्षक की पृष्ठभूमि को प्रभावित करता है, बाकी चयनित खंड की पृष्ठभूमि के रंग को नहीं।

संक्षेप में, आप UISegmentedControliOS 13 में वर्तमान में चयनित खंड के पृष्ठभूमि रंग को कैसे संशोधित करते हैं ? क्या सार्वजनिक एपीआई का उपयोग करते हुए एक उचित समाधान है, जिसे निजी उप-संरचना में खुदाई की आवश्यकता नहीं है?

IOS 13 में कोई नई प्रॉपर्टी है UISegmentedControlया UIControlनहीं और इनमें से कोई भी बदलाव UIViewप्रासंगिक नहीं है।

जवाबों:


134

IOS 13b3 के रूप में, अब selectedSegmentTintColorऑन है UISegmentedControl

खंडित नियंत्रण के समग्र रंग को बदलने के लिए इसका उपयोग करें backgroundColor

चयनित खंड के उपयोग का रंग बदलने के लिए selectedSegmentTintColor

अचयनित खंड शीर्षकों के रंग / फ़ॉन्ट को बदलने के लिए, / की setTitleTextAttributesस्थिति के साथ उपयोग करें ।.normalUIControlStateNormal

चयनित खंड खिताब के रंग / font, उपयोग को बदलने के लिए setTitleTextAttributesके एक राज्य के साथ .selected/ UIControlStateSelected

यदि आप छवियों के साथ एक खंडित नियंत्रण बनाते हैं, यदि छवियों को टेम्पलेट छवियों के रूप में बनाया जाता है, तो छवियों tintColorको रंगने के लिए खंडित नियंत्रण का उपयोग किया जाएगा। लेकिन यह एक समस्या है। यदि आप tintColorउसी रंग को सेट करते हैं selectedSegmentTintColorतो छवि चयनित सेगमेंट में दिखाई नहीं देगी। यदि आप tintColorउसी रंग के रूप में सेट करते हैं backgroundColor, तो अचयनित खंडों पर चित्र दिखाई नहीं देंगे। इसका मतलब है कि छवियों के साथ आपका खंडित नियंत्रण दिखाई देने वाली हर चीज़ के लिए 3 अलग-अलग रंगों का उपयोग करना चाहिए। या आप गैर-टेम्पलेट छवियों का उपयोग कर सकते हैं और सेट नहीं कर सकते हैं tintColor

IOS 12 या उससे पहले के तहत, बस खंडित नियंत्रण सेट करें tintColorया ऐप के समग्र रंग पर निर्भर करें।


हम सीमाओं के बिना खंड नियंत्रक कैसे सेट करते हैं? मुझे इसके लिए iOS 13. में कोई सेटिंग दिखाई नहीं दे रही है। इससे पहले, बॉर्डर सेगमेंट कंट्रोल पाने के लिए टिंटकलर सेट करना काफी था।
दीपक शर्मा

कृपया बॉर्डर कलर आदि जोड़ें ताकि सभी सभी सेगमेंट पा सकें। कलर संबंधी समस्याएँ यहाँ हल हो गई हैं। क्या कहते हो ? :)
योगेश पटेल ५

1
@YogeshPatel सीमा के रंग के बारे में क्या? IOS 13 और iOS 12 में कोई बॉर्डर कलर नहीं है, यह इसके साथ सेट है tintColorजो पहले से ही उत्तर में कवर किया गया है।
रामादेवी

@rmaddy मैंने इसे [सेगमेंटकंट्रोल.लेयर सेटबॉर्डरकलर: [[यूआईसीकल व्हाइटकॉलर] सीजीकोलर]]; [sectionedControl.layer setBorderWidth: 0.5]; यह मुझे सीमा और सीमा रंग आईओएस 13. में देता है
योगेश पटेल

1
ओह, वह सीमा। यह किसी भी दृष्टिकोण पर लागू होता है, न कि केवल एक खंडित नियंत्रण पर। यह मूल प्रश्न और इस उत्तर के दायरे से परे है। आपकी टिप्पणी ही काफी है।
रामप्यारी

47

Xcode 11 बीटा 3 के रूप में

अभी selectedSegmentTintColorसंपत्ति है UISegmentedControl

देखिए रामदयाल का जवाब


IOS 12 उपस्थिति वापस पाने के लिए

मैं चयनित सेगमेंट का रंग टिंट करने में सक्षम नहीं था, उम्मीद है कि यह आगामी बीटा में तय किया जाएगा।

चयनित राज्य की पृष्ठभूमि छवि सेट करना सामान्य राज्य की पृष्ठभूमि छवि को सेट किए बिना काम नहीं करता है (जो सभी iOS 13 स्टाइल को हटा देता है)

लेकिन मैं इसे वापस आईओएस 12 उपस्थिति (या पर्याप्त के पास, मैं कोने के त्रिज्या को उसके छोटे आकार में वापस करने में सक्षम नहीं था) में वापस लाने में सक्षम था।

यह आदर्श नहीं है, लेकिन एक चमकदार सफेद खंडित नियंत्रण हमारे ऐप में थोड़ा बाहर दिखता है।

(नहीं पता UIImage(color:)था कि हमारे कोडबेस में एक एक्सटेंशन तरीका था। लेकिन इसे लागू करने का कोड वेब के आसपास है)

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
        }
    }
}

उपरोक्त कोड का प्रभाव दिखाने वाली छवि


यह एक अच्छा समाधान हो सकता है। मैं अभी तक यह कोशिश करने का मौका है, लेकिन नहीं किया है यह भी करने के लिए एक फोन की आवश्यकता होती है setTitleTextAttributesचयनित खंड के शीर्षक एक सफेद रंग है बनाने के लिए?
राम

हम्म, ऐसा लग रहा है, लेकिन यह प्रतीत नहीं होना चाहिए। मुझे उस कोड उपयोग एटीएम तक पहुंच नहीं मिली है, लेकिन बाईं ओर की छवि उस कोड के साथ बनाई गई है।
जोनाथन।

8
UIImage (रंग :) एक्सटेंशन के लिए stackoverflow.com/a/33675160/5790492
निक कोव

1
यह अच्छा होगा यदि आप UIImage एक्सटेंशन जोड़ेंगे, इस तरह, आपका उत्तर पूर्ण नहीं है iho
फ्रेडफ्लिंसस्टोन

1
@VityaShurapov के लिए इसकी स्थापना तब होती है जब इसे हाइलाइट किया गया और चयनित किया जाता है, यह राज्यों की एक सरणी नहीं है, बल्कि इसमें एक विकल्प सेट किया गया है, जिसका अर्थ है कि नए राज्य बनाने के लिए मूल्यों को संयुक्त किया गया है।
जोनाथन।

36

IOS 13 और स्विफ्ट 5.0 (Xcode 11.0) सेगमेंट कंट्रोल 100% काम कर रहा है

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें

 if #available(iOS 13.0, *) {
      yoursegmentedControl.backgroundColor = UIColor.black
      yoursegmentedControl.layer.borderColor = UIColor.white.cgColor
      yoursegmentedControl.selectedSegmentTintColor = UIColor.white
      yoursegmentedControl.layer.borderWidth = 1

      let titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]    
      yoursegmentedControl.setTitleTextAttributes(titleTextAttributes, for:.normal)

      let titleTextAttributes1 = [NSAttributedString.Key.foregroundColor: UIColor.black]
      yoursegmentedControl.setTitleTextAttributes(titleTextAttributes1, for:.selected)
  } else {
              // Fallback on earlier versions
}

7
क्या आपने पृष्ठभूमि को सफेद के रूप में सेट करने की कोशिश की? मेरे लिए यह ग्रेनेश आ रहा है
रोनित

@ इयान हंट जो आप एक्सकोड और स्विफ्ट भाषा का उपयोग कर रहे हैं?
मौलिक पटेल

@Ronit ऑफकोर्स !! मैं कोशिश करूँगा लेकिन plz मुझे बताएं कि किस प्रकार का आउटपुट डिस्प्ले अब
मौलिक पटेल

स्विफ्ट 5, xcode 11.3! यह दिखाता है कि यह क्या चाहता है! मैं जो नहीं चाहता हूं :)
इटान हंट

15

मैंने वर्कअराउंड की कोशिश की है और यह मेरे लिए बहुत अच्छा काम करता है। यहाँ उद्देश्य-सी संस्करण है:

@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

2
मुझे यकीन नहीं है कि यह साथ काम करेगा CGRectMake(0.0f, 0.0f, 1.0f, 1.0f): Xcode 11 बीटा के साथ मेरे परीक्षणों rectसे, खंड के नियंत्रण की सीमा के समान आकार होना चाहिए।
œ --œ

2
IOS13 बीटा 6 के बाद से tintcolor एक चयनित बटन पर नहीं दिखा, इसलिए मुझे एक पंक्ति जोड़नी पड़ी: [self setTitleTextAttributes: @ {NSForegroundColorAttributeName: UIColor .blackColor, NSFontAttributeName: [UIFont systemFontOfSize: 13};
पीटर जॉनसन

जब मैं इस पर प्रयोग करने की कोशिश करता हूं तो मुझे [[UISegmentedControl appearance] ensureiOS12Style]एक अपवाद मिलता है। कोई अंदाज़ा है कि क्या चल रहा है? Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSMethodSignature getArgumentTypeAtIndex:]: index (2) out of bounds [0, 1]'
जेरेमी हिक्स

13

Xcode 11 बीटा 3 के रूप में

अभी selectedSegmentTintColorसंपत्ति है UISegmentedControl

थैंक यू @rmaddy!


मूल उत्तर, Xcode 11 बीटा और बीटा 2 के लिए

क्या सार्वजनिक एपीआई का उपयोग करते हुए एक उचित समाधान है, जिसे निजी उप-संरचना में खुदाई की आवश्यकता नहीं है?

Xcode 11.0 बीटा के साथ, इसे नियमों के अनुसार करना एक चुनौती प्रतीत होती है, क्योंकि मूल रूप से इसे हर राज्य के लिए सभी पृष्ठभूमि छवियों को गोल कोनों, पारदर्शिता और के साथ फिर से तैयार करना पड़ता है resizableImage(withCapInsets:)। उदाहरण के लिए, आपको निम्न के समान रंगीन छवि बनानी होगी:
यहां छवि विवरण दर्ज करें

तो अब के लिए, चलो- dig-in-the-the-subviews रास्ता बहुत आसान लगता है:

class TintedSegmentedControl: UISegmentedControl {

    override func layoutSubviews() {
        super.layoutSubviews()

        if #available(iOS 13.0, *) {
            for subview in subviews {
                if let selectedImageView = subview.subviews.last(where: { $0 is UIImageView }) as? UIImageView,
                    let image = selectedImageView.image {
                    selectedImageView.image = image.withRenderingMode(.alwaysTemplate)
                    break
                }
            }
        }
    }
}

यह समाधान सही ढंग से चयन के लिए टिंट रंग लागू करेगा, जैसे: यहां छवि विवरण दर्ज करें


1
पुरस्कृत क्योंकि समय समाप्त हो रहा है, लेकिन अधिमानतः एक समाधान जिसमें निजी पदानुक्रम में खुदाई शामिल नहीं है :)
जोनाथन।

@Jonathan। धन्यवाद। पदानुक्रम को देखते हुए आपको पहले से ही निकटतम समाधान मिल गया था: क्योंकि एक बार आपके setBackgroundImageलिए .normal, आपको अन्य सभी छवियों (अन्य राज्यों सहित setDividerImage) को सेट करना होगा , शायद कुछ के साथ UIBezierPathऔर resizableImage(withCapInsets:), जो कि अगर हम iOS 13 डिज़ाइन चाहते हैं तो यह अत्यधिक जटिल हो जाता है इस तरफ।
कूर

हाँ, आदर्श रूप से यह एक बीटा में तय किया जाएगा
जोनाथन।

3
यह अब iOS 13b3 के रूप में की जरूरत नहीं है। अभी selectedSegmentTintColorसंपत्ति है UISegmentedControl
व्याघ्र जूल

11

@ इलाहि चारफेदीन जवाब का स्विफ्ट संस्करण:

if #available(iOS 13.0, *) {
   segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
   segmentedControl.selectedSegmentTintColor = UIColor.blue
} else {
   segmentedControl.tintColor = UIColor.blue
}

10
if (@available(iOS 13.0, *)) {

    [self.segmentedControl setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont systemFontOfSize:13]} forState:UIControlStateSelected];
    [self.segmentedControl setSelectedSegmentTintColor:[UIColor blueColor]];

} else {

[self.segmentedControl setTintColor:[UIColor blueColor]];}

7

iOS13 UISegmentController

कैसे इस्तेमाल करे:

segment.setOldLayout(tintColor: .green)

extension UISegmentedControl
{
    func setOldLayout(tintColor: UIColor)
    {
        if #available(iOS 13, *)
        {
            let bg = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
             let devider = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))

             //set background images
             self.setBackgroundImage(bg, for: .normal, barMetrics: .default)
             self.setBackgroundImage(devider, for: .selected, barMetrics: .default)

             //set divider color
             self.setDividerImage(devider, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)

             //set border
             self.layer.borderWidth = 1
             self.layer.borderColor = tintColor.cgColor

             //set label color
             self.setTitleTextAttributes([.foregroundColor: tintColor], for: .normal)
             self.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
        }
        else
        {
            self.tintColor = tintColor
        }
    }
}
extension UIImage {
    convenience init(color: UIColor, size: CGSize) {
        UIGraphicsBeginImageContextWithOptions(size, false, 1)
        color.set()
        let ctx = UIGraphicsGetCurrentContext()!
        ctx.fill(CGRect(origin: .zero, size: size))
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        self.init(data: image.pngData()!)!
    }
}

1
यह एकमात्र दृष्टिकोण है जो मेरे लिए काम करता है - पृष्ठभूमि छवियां। कुछ कारणों से SelectSegmentTintColor ने काम नहीं किया।
डेनुकैम

7

XCODE 11.1 और iOS 13

@ जिगर दरजी के जवाब पर आधारित है लेकिन एक सुरक्षित कार्यान्वयन।

हम पहले एक सुविधा सुविधा आरंभक बनाते हैं:

extension UIImage {

convenience init?(color: UIColor, size: CGSize) {
    UIGraphicsBeginImageContextWithOptions(size, false, 1)
    color.set()
    guard let ctx = UIGraphicsGetCurrentContext() else { return nil }
    ctx.fill(CGRect(origin: .zero, size: size))
    guard
        let image = UIGraphicsGetImageFromCurrentImageContext(),
        let imagePNGData = image.pngData()
        else { return nil }
    UIGraphicsEndImageContext()

    self.init(data: imagePNGData)
   }
}

फिर हम UISegmentedControl का विस्तार करते हैं:

extension UISegmentedControl {

func fallBackToPreIOS13Layout(using tintColor: UIColor) {
    if #available(iOS 13, *) {
        let backGroundImage = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
        let dividerImage = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))

        setBackgroundImage(backGroundImage, for: .normal, barMetrics: .default)
        setBackgroundImage(dividerImage, for: .selected, barMetrics: .default)

        setDividerImage(dividerImage,
                        forLeftSegmentState: .normal,
                        rightSegmentState: .normal, barMetrics: .default)

        layer.borderWidth = 1
        layer.borderColor = tintColor.cgColor

        setTitleTextAttributes([.foregroundColor: tintColor], for: .normal)
        setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
    } else {
        self.tintColor = tintColor
    }
  }
}

उत्तम! धन्यवाद!
सेनोकिको स्टेलियन

5

यहाँ मेरा जोनाथन पर लिया गया है। Xamarin.iOS (C #) के लिए जवाब है, लेकिन छवि आकार के लिए सुधार के साथ। कॉलिन ब्लेक के जवाब पर Cur की टिप्पणी के साथ, मैंने खंडित नियंत्रण के आकार को विभाजित करने के अलावा सभी चित्र बनाए। विभक्त खंड का 1xheight है।

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

3

आप निम्न विधि को लागू कर सकते हैं

extension UISegmentedControl{
    func selectedSegmentTintColor(_ color: UIColor) {
        self.setTitleTextAttributes([.foregroundColor: color], for: .selected)
    }
    func unselectedSegmentTintColor(_ color: UIColor) {
        self.setTitleTextAttributes([.foregroundColor: color], for: .normal)
    }
}

उपयोग कोड

segmentControl.unselectedSegmentTintColor(.white)
segmentControl.selectedSegmentTintColor(.black)

0

जबकि ऊपर दिए गए उत्तर बहुत अच्छे हैं, उनमें से अधिकांश चयनित खंड के अंदर पाठ के रंग को गलत पाते हैं। मैंने UISegmentedControlसबक्लास बनाया है जिसे आप iOS 13 और प्री-iOS 13 डिवाइस पर उपयोग कर सकते हैं और टिंटकलर प्रॉपर्टी का उपयोग कर सकते हैं जैसा कि आप प्री iOS 13 डिवाइस पर करेंगे।

    class LegacySegmentedControl: UISegmentedControl {
        private func stylize() {
            if #available(iOS 13.0, *) {
                selectedSegmentTintColor = tintColor
                let tintColorImage = UIImage(color: tintColor)
                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

// Detect underlying backgroundColor so the text color will be properly matched

                if let background = backgroundColor {
                    self.setTitleTextAttributes([.foregroundColor: background, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
                } else {
                    func detectBackgroundColor(of view: UIView?) -> UIColor? {
                        guard let view = view else {
                            return nil
                        }
                        if let color = view.backgroundColor, color != .clear {
                            return color
                        }
                        return detectBackgroundColor(of: view.superview)
                    }
                    let textColor = detectBackgroundColor(of: self) ?? .black

                    self.setTitleTextAttributes([.foregroundColor: textColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
                }
            }
        }

        override func tintColorDidChange() {
            super.tintColorDidChange()
            stylize()
        }
    }

    fileprivate extension UIImage {
        public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
          let rect = CGRect(origin: .zero, size: size)
          UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
          color.setFill()
          UIRectFill(rect)
          let image = UIGraphicsGetImageFromCurrentImageContext()
          UIGraphicsEndImageContext()

          guard let cgImage = image?.cgImage else { return nil }
          self.init(cgImage: cgImage)
        }
    }

tintColorDidChangeविधि का उपयोग करते हुए हम यह सुनिश्चित करते हैं कि खंड दृश्य पर संपत्ति परिवर्तन या किसी भी अंतर्निहित विचार, जिसे iOS के लिए पसंदीदा व्यवहार है, stylizeहर बार विधि को कहा जाएगा tintColor

परिणाम: यहां छवि विवरण दर्ज करें


-2

यदि आप गोल कोनों नहीं चाहते हैं, तो जोनाथन के उत्तर पर थोड़ा विस्तार करें

extension UISegmentedControl {
    /// Tint color doesn't have any effect on iOS 13.
    func ensureiOS12Style(roundCorner: Bool = true) {
        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)

            if !roundCorner {
                layer.masksToBounds = false

                let borderView = UIView()
                borderView.layer.borderWidth = 1
                borderView.layer.borderColor = UIColor.black.cgColor
                borderView.isUserInteractionEnabled = false
                borderView.translatesAutoresizingMaskIntoConstraints = false

                addSubview(borderView)

                NSLayoutConstraint(item: borderView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
                NSLayoutConstraint(item: borderView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
                NSLayoutConstraint(item: borderView, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1, constant: 0).isActive = true
                NSLayoutConstraint(item: borderView, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1, constant: 0).isActive = true
            }
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.