İOS 13'te UISegmentedControl'de bir segmentin renkleri nasıl değiştirilir?


110

A UISegmentedControl, iOS 13'te yeni bir görünüme sahip ve segmentli kontrolün renklerini değiştirmek için mevcut kod artık eskisi gibi çalışmıyor.

İOS 13'ten önce tintColor, bölümlere ayrılmış kontrolün etrafındaki kenarlık, bölümler arasındaki çizgiler ve seçilen bölümün arka plan rengi için kullanılacak olan ve bunu ayarlayabiliyordunuz . Ardından, ön plan rengi özelliğini ile kullanarak her bölümün başlıklarının rengini değiştirebilirsiniz titleTextAttributes.

İOS 13 altında tintColorhiçbir şey yapmaz. Segmentli kontrolleri, segmentli kontrolün backgroundColorgenel rengini değiştirecek şekilde ayarlayabilirsiniz . Ancak seçilen bölümün arka planı olarak kullanılan rengi değiştirmenin bir yolunu bulamıyorum. Metin niteliklerinin ayarlanması hala çalışıyor. Hatta başlığın arka plan rengini ayarlamayı bile denedim, ancak bu seçilen bölümün arka plan renginin geri kalanını değil, yalnızca başlığın arka planını etkiliyor.

Kısacası, UISegmentedControliOS 13'te şu anda seçili olan bir segmentin arka plan rengini nasıl değiştirirsiniz ? Özel alt görünüm yapısını derinlemesine incelemeyi gerektirmeyen, genel API'leri kullanan uygun bir çözüm var mı?

İOS 13'te yeni özellik yok UISegmentedControlveya bu özellikteki UIControldeğişikliklerin hiçbiri UIViewalakalı değil.

Yanıtlar:


134

İOS 13b3 itibariyle artık var selectedSegmentTintColorüzerinde UISegmentedControl.

Segmentli kontrolün genel rengini değiştirmek için, onun backgroundColor.

Seçilen segmentin rengini değiştirmek için kullanın selectedSegmentTintColor.

Seçilmemiş bölüm başlıklarının rengini / yazı tipini değiştirmek için setTitleTextAttributes, .normal/ durumuyla kullanın UIControlStateNormal.

Seçilen bölüm başlıklarının rengini / yazı tipini değiştirmek için setTitleTextAttributes, .selected/ durumuyla birlikte kullanın UIControlStateSelected.

Görüntülerle bölümlenmiş bir kontrol oluşturursanız, görüntüler şablon görüntüler olarak oluşturulursa, bu durumda bölümlere ayrılmış kontroller tintColorgörüntüleri renklendirmek için kullanılacaktır. Ama bunun bir sorunu var. O zamanki ile tintColoraynı renge ayarlarsanız, selectedSegmentTintColorgörüntü seçilen segmentte görünmez. Öğesini tintColorile aynı renge ayarlarsanız, backgroundColorseçili olmayan bölümlerdeki görüntüler görünmez. Bu, her şeyin görünür olması için resimlerle bölümlenmiş kontrolünüzün 3 farklı renk kullanması gerektiği anlamına gelir. Veya şablon olmayan resimleri kullanabilir ve tintColor.

İOS 12 veya önceki sürümler altında, segmentli kontrolleri ayarlayın tintColorveya uygulamanın genel renk tonu rengine güvenin.


Segment denetleyicisini sınırlar olmadan nasıl ayarlayabiliriz? İOS 13'te bunun için bir ayar görmüyorum. Daha önce, renk tonunu ayarlamak, kenarlıksız bir segment kontrolü elde etmek için yeterliydi.
Deepak Sharma

Lütfen Kenar Rengi vb. Ekleyin, böylece tüm segment Renk ile ilgili sorunlar burada çözülür. ne söyler ? :)
Yogesh Patel

1
@YogeshPatel Kenarlık rengi ne olacak? İOS 13'te kenarlık rengi yoktur ve iOS 12'de tintColorzaten cevapta kapsanan ayarlanmıştır .
rmaddy

@rmaddy Bunu [segmentedControl.layer setBorderColor: [[UIColor whiteColor] CGColor]] olarak ayarladım; [segmentedControl.layer setBorderWidth: 0.5]; iOS 13'te kenarlık ve kenarlık rengi veriyor.
Yogesh Patel

1
Oh, bu sınır. Bu, yalnızca bölümlere ayrılmış bir kontrol değil, herhangi bir görünüm için geçerlidir. Bu, orijinal sorunun ve bu cevabın kapsamı dışındadır. Yorumunuz yeterli.
rmaddy

48

Xcode 11 beta 3'ten itibaren

Artık selectedSegmentTintColormülk var UISegmentedControl.

Rmaddy'nin cevabına bakın


İOS 12 görünümünü geri almak için

Seçili segmentin rengini tonlandıramadım, umarım önümüzdeki bir beta sürümde düzeltilecektir.

Seçili durumun arka plan görüntüsünü ayarlamak, normal durumun arka plan görüntüsünü ayarlamadan çalışmaz (bu, tüm iOS 13 stilini kaldırır)

Ancak onu iOS 12 görünümüne geri getirmeyi başardım (veya yeterince yakın, köşe yarıçapını daha küçük boyutuna döndüremedim).

İdeal değil, ancak parlak beyaz bölümlü bir kontrol, uygulamamızda biraz yerinde görünmüyor.

( UIImage(color:)Kod tabanımızda bir genişletme yöntemi olduğunun farkında değildik. Ancak onu uygulamak için gereken kod web'de)

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

Yukarıdaki kodun etkisini gösteren resim


Bu iyi bir çözüm olabilir. Henüz bunu deneme şansım olmadı, ancak bu aynı zamanda setTitleTextAttributesseçilen segmentin başlığının beyaz renge sahip olması için bir çağrı gerektiriyor mu?
rmaddy

Hmm, olması gerektiği gibi görünüyor ama görünüşe göre değil. Bu kod kullanımı atm'ye erişimim yok, ancak soldaki görüntü bu kodla oluşturuldu.
Jonathan.

8
UIImage (renk :) uzantısı için stackoverflow.com/a/33675160/5790492 .
Nik Kov

1
UIImage uzantısını eklerseniz iyi olur, bu şekilde cevabınız tam değildir iho
FredFlinstone

1
@VityaShurapov onun hem Vurgulandığında şeklinde ayarlayarak ve seçildikten sonra saat değerleri yeni bir devlet oluşturmak için birleştirildiği anlamına geçirilen devletler ziyade bir seçenek kümesinin bir dizi, değil.
Jonathan.

37

IOS 13 ve Swift 5.0 (Xcode 11.0) Segment Kontrolü% 100 Çalışıyor

görüntü açıklamasını buraya girin

görüntü açıklamasını buraya girin

 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
}

8
arka planı beyaz olarak ayarlamayı denedin mi? benim için grimsi geliyor
Ronit

@ItanHant hangi xcode ve swift dilini kullanıyorsunuz?
Maulik Patel

@Ronit ofcourse !! deneyeceğim ama lütfen bana ne tür çıktı görüntülendiğini söyle
Maulik Patel

swift 5, xcode 11.3! ne istediğini gösterir! istediğim değil :)
Itan Hant

16

Geçici çözümü denedim ve benim için harika çalışıyor. İşte Objective-C sürümü:

@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)İle çalışacağından emin değilim : Xcode 11 beta ile yaptığım testlere rectgöre, bölümlere ayrılmış kontrolün sınırları ile aynı boyutta olmalıydı.
Cœur

2
İOS13 beta 6'dan beri, renk tonu seçilen bir düğmede görünmedi, bu yüzden bir satır eklemem gerekiyordu: [self setTitleTextAttributes: @ {NSForegroundColorAttributeName: UIColor.blackColor, NSFontAttributeName: [UIFont systemFontOfSize: 13]} forState: UIFont systemFontOfSize: 13]};
Peter Johnson

Bunu kullanmaya çalıştığımda [[UISegmentedControl appearance] ensureiOS12Style]bir istisna yaşıyorum. Neler olup bittiği hakkında bir fikrin var mı? Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSMethodSignature getArgumentTypeAtIndex:]: index (2) out of bounds [0, 1]'
Jeremy Hicks

13

Xcode 11 beta 3'ten itibaren

Şimdi var selectedSegmentTintColormülk var UISegmentedControl.

Teşekkür ederim @rmaddy!


Xcode 11 beta ve beta 2 için orijinal cevap

Özel alt görünüm yapısını derinlemesine incelemeyi gerektirmeyen, genel API'leri kullanan uygun bir çözüm var mı?

Xcode 11.0 beta ile, bunu kurallara göre yapmak zor görünüyor, çünkü temelde her durum için tüm arka plan görüntülerini kendi başınıza, yuvarlak köşeler, şeffaflık ve resizableImage(withCapInsets:). Örneğin, aşağıdakilere benzer renkli bir görüntü oluşturmanız gerekir:
görüntü açıklamasını buraya girin

Bu yüzden şimdilik, alt görünümleri araştıralım yolu çok daha kolay görünüyor:

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

Bu çözüm, aşağıdaki gibi renk tonunu seçime doğru şekilde uygulayacaktır: görüntü açıklamasını buraya girin


1
Zaman tükendiği için ödüllendirildi, ancak tercihen özel hiyerarşiye girmeyi içermeyen bir çözüm bulunacaktır :)
Jonathan.

@Jonathan. Teşekkür ederim. Size bir kez çünkü: Zaten en yakın çözüm hiyerarşisinde bakarak içermeyen var setBackgroundImageiçin .normal, (diğer devletler ve dahil olmak üzere tüm diğer görüntüleri ayarlamak zorunda setDividerImage) muhtemelen bazı ile UIBezierPathve resizableImage(withCapInsets:)iOS 13 tasarım istiyorsanız aşırı karmaşık hale getiren bu yoldan.
Cœur

Evet, ideal olarak bir beta sürümde düzeltilecek
Jonathan.

3
Bu, iOS 13b3'ten itibaren artık gerekli değildir. Artık selectedSegmentTintColormülk var UISegmentedControl.
rmaddy

11

@Ilahi Charfeddine cevabının hızlı versiyonu:

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

nasıl kullanılır:

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
Bu benim için işe yarayan tek yaklaşım - arka plan resimleri. selectedSegmentTintColor herhangi bir nedenle çalışmadı.
DenNukem

7

XCODE 11.1 ve iOS 13

@Jigar Darji'nin cevabına dayanıyor, ancak daha güvenli bir uygulama.

İlk olarak, uygun olmayan bir başlatıcı oluşturuyoruz:

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

Ardından UISegmentedControl'ü genişletiyoruz:

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

Mükemmel! Teşekkür ederim!
Senocico Stelian

5

İşte Jonathan.'ın Xamarin.iOS (C #) için cevabını, ancak görüntü boyutlandırma düzeltmeleriyle birlikte. Cœur'un Colin Blake'in cevabı hakkındaki yorumunda olduğu gibi, bölücü hariç tüm görüntüleri bölümlere ayrılmış kontrolün boyutunda yaptım. Bölücü, segmentin 1 katıdır.

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

Aşağıdaki yöntemi uygulayabilirsiniz

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

Kullanım kodu

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

2

Yukarıdaki cevaplar harika olsa da, çoğu seçilen bölümdeki metnin rengini yanlış alıyor. UISegmentedControlİOS 13 ve iOS 13 öncesi cihazlarda kullanabileceğiniz ve iOS 13 öncesi cihazlarda olduğu gibi tintColor özelliğini kullanabileceğiniz alt sınıf oluşturdum .

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

tintColorDidChangeYöntemi kullanarak , stylizeyöntemin tintColor, segment görünümünde veya iOS'ta tercih edilen davranış olan temel görünümlerden herhangi birinde özellik her değiştiğinde çağrılacağından emin oluruz .

Sonuç: görüntü açıklamasını buraya girin


-2

Yuvarlak köşeler istememeniz durumunda Jonathan cevabını biraz genişletmek

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
            }
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.