Como alterar as cores de um segmento em um UISegmentedControl no iOS 13?

109

A UISegmentedControltem uma nova aparência no iOS 13 e o código existente para alterar as cores do controle segmentado não funciona mais como antes.

Antes do iOS 13, você podia definir o tintColore que seria usado para a borda ao redor do controle segmentado, as linhas entre os segmentos e a cor de fundo do segmento selecionado. Em seguida, você pode alterar a cor dos títulos de cada segmento usando o atributo de cor de primeiro plano com titleTextAttributes.

No iOS 13, o tintColornão faz nada. Você pode definir o controle segmentado backgroundColorpara alterar a cor geral do controle segmentado. Mas não consigo encontrar nenhuma maneira de alterar a cor usada como fundo do segmento selecionado. Definir os atributos de texto ainda funciona. Eu até tentei definir a cor de fundo do título, mas isso afeta apenas o fundo do título, não o resto da cor de fundo do segmento selecionado.

Em suma, como você modifica a cor de fundo do segmento atualmente selecionado de a UISegmentedControlno iOS 13? Existe uma solução adequada, usando APIs públicas, que não exija cavar na estrutura de subvisualização privada?

Não há novas propriedades no iOS 13 para UISegmentedControlou UIControle nenhuma das alterações UIViewé relevante.

rmaddy
fonte

Respostas:

134

A partir de iOS 13b3, existe agora uma selectedSegmentTintColoron UISegmentedControl.

Para alterar a cor geral do controle segmentado, use seu backgroundColor.

Para alterar a cor do segmento selecionado, use selectedSegmentTintColor.

Para alterar a cor / fonte dos títulos de segmento não selecionados, use setTitleTextAttributescom um estado de .normal/ UIControlStateNormal.

Para alterar a cor / fonte dos títulos do segmento selecionado, use setTitleTextAttributescom um estado de .selected/UIControlStateSelected .

Se você criar um controle segmentado com imagens, se as imagens forem criadas como imagens de modelo, os controles segmentados tintColorserão usados ​​para colorir as imagens. Mas isso tem um problema. Se você definir o tintColorpara a mesma cor selectedSegmentTintColor, a imagem não ficará visível no segmento selecionado. Se você definir o tintColorcom a mesma cor de backgroundColor, as imagens nos segmentos não selecionados não ficarão visíveis. Isso significa que seu controle segmentado com imagens deve usar 3 cores diferentes para que tudo fique visível. Ou você pode usar imagens sem modelo e não definir o tintColor.

No iOS 12 ou anterior, basta definir os controles segmentados tintColorou confiar na cor geral do aplicativo.

rmaddy
fonte
Como definimos o controlador de segmento sem fronteiras? Não vejo configuração para isso no iOS 13. Anteriormente, definir tintcolor era o suficiente para obter um controle de segmento sem borda.
Deepak Sharma
Adicione a cor da borda etc. para que todos possam encontrar todos os problemas relacionados à cor do segmento são resolvidos aqui. o que diz ? :)
Yogesh Patel
1
@YogeshPatel E quanto à cor da borda? Não há cor de borda no iOS 13 e no iOS 12 está definida com a tintColorqual já foi abordada na resposta.
rmaddy de
@rmaddy Eu defini este [segmentedControl.layer setBorderColor: [[UIColor whiteColor] CGColor]]; [segmentedControl.layer setBorderWidth: 0,5]; ele me dá borda e cor da borda no iOS 13.
Yogesh Patel
1
Oh, essa fronteira. Isso se aplica a qualquer visualização, não apenas a um controle segmentado. Isso está além do escopo da pergunta original e desta resposta. Seu comentário é o suficiente.
rmaddy
47

A partir do Xcode 11 beta 3

Agora existe a selectedSegmentTintColorpropriedade ligada UISegmentedControl.

Veja a resposta de rmaddy


Para voltar a aparência do iOS 12

Não fui capaz de tingir a cor do segmento selecionado, espero que seja corrigido em um próximo beta.

Definir a imagem de fundo do estado selecionado não funciona sem definir a imagem de fundo do estado normal (que remove todo o estilo do iOS 13)

Mas consegui voltar à aparência do iOS 12 (ou perto o suficiente, não consegui retornar o raio do canto ao seu tamanho menor).

Não é o ideal, mas um controle segmentado branco brilhante parece um pouco fora do lugar em nosso aplicativo.

(Não percebi que UIImage(color:)era um método de extensão em nossa base de código. Mas o código para implementá-lo está em toda a 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
        }
    }
}

Imagem mostrando o efeito do código acima

Jonathan.
fonte
Esta pode ser uma boa solução alternativa. Ainda não tive a oportunidade de experimentar, mas também é necessário ligar para setTitleTextAttributespara que o título do segmento selecionado seja branco?
rmaddy
Hmm, parece que deveria, mas aparentemente não. Não tenho acesso a esse atm de uso de código, mas a imagem à esquerda foi criada com esse código.
Jonathan.
8
stackoverflow.com/a/33675160/5790492 para extensão UIImage (color :).
Nik Kov
1
Seria bom se você adicionasse a extensão UIImage, dessa forma, sua resposta não está completa iho
FredFlinstone
1
@VityaShurapov sua configuração para quando é realçado e selecionado, não é um array de estados passados, mas sim um conjunto de opções, o que significa que os valores são combinados para criar um novo estado.
Jonathan.
36

IOS 13 e Swift 5.0 (Xcode 11.0) Segment Control 100% Working

insira a descrição da imagem aqui

insira a descrição da imagem aqui

 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
}
Maulik Patel
fonte
7
você tentou definir o fundo como branco? para mim está ficando acinzentado
Ronit
@ItanHant, qual xcode e linguagem swift você está usando?
Maulik Patel
@Ronit ofcourse !! Vou tentar, mas por favor diga-me que tipo de exibição de saída agora
Maulik Patel
swift 5, xcode 11.3! mostra o que quer! não é o que eu quero :)
Itan Hant
15

Eu tentei a solução alternativa e funciona muito bem para mim. Aqui está a versão 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
Colin Blake
fonte
2
Não tenho certeza se vai funcionar com CGRectMake(0.0f, 0.0f, 1.0f, 1.0f): dos meus testes com Xcode 11 beta, recttinha que ser do mesmo tamanho que os limites do controle segmentado.
Cœur
2
Desde iOS13 beta 6, o tintcolor não apareceu em um botão selecionado, então eu tive que adicionar uma linha: [self setTitleTextAttributes: @ {NSForegroundColorAttributeName: UIColor.blackColor, NSFontAttributeName: [UIFont systemFontOtrolfSize: 13]} forState: UIConected]
Peter Johnson
Quando tento usar isso [[UISegmentedControl appearance] ensureiOS12Style], recebo uma exceção. alguma ideia do que está acontecendo? Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSMethodSignature getArgumentTypeAtIndex:]: index (2) out of bounds [0, 1]'
Jeremy Hicks
13

A partir do Xcode 11 beta 3

Agora existe a selectedSegmentTintColorpropriedade ligada UISegmentedControl.

Obrigado @rmaddy!


Resposta original, para Xcode 11 beta e beta 2

Existe uma solução adequada, usando APIs públicas, que não exija cavar na estrutura de subvisualização privada?

Com o Xcode 11.0 beta, parece ser um desafio fazê-lo pelas regras, porque basicamente requer redesenhar todas as imagens de fundo para cada estado por você mesmo, com cantos arredondados, transparência e resizableImage(withCapInsets:). Por exemplo, você precisaria gerar uma imagem colorida semelhante a:
insira a descrição da imagem aqui

Então, por enquanto, a maneira vamos-cavar-nos-subviews parece muito mais fácil:

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

Esta solução aplicará corretamente a cor da tonalidade à seleção, como em: insira a descrição da imagem aqui

Cœur
fonte
1
Concedido porque o tempo está se esgotando, mas de preferência será encontrada uma solução que não envolva cavar na hierarquia privada :)
Jonathan.
@Jonathan. Obrigado. Você já tem a solução mais próximo não envolvendo olhando para a hierarquia: porque uma vez que você setBackgroundImagepara .normal, você tem que definir todas as outras imagens (incluindo outros estados e setDividerImage), provavelmente com alguma UIBezierPathe resizableImage(withCapInsets:), o que torna excessivamente complexa se queremos que o projeto iOS 13 deste jeito.
Cœur
Sim, o ideal é que seja corrigido em um beta
Jonathan.
3
Isso não é mais necessário a partir do iOS 13b3. Agora existe a selectedSegmentTintColorpropriedade ligada UISegmentedControl.
rmaddy
11

Versão rápida da resposta @Ilahi Charfeddine:

if #available(iOS 13.0, *) {
   segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
   segmentedControl.selectedSegmentTintColor = UIColor.blue
} else {
   segmentedControl.tintColor = UIColor.blue
}
Vignan S
fonte
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]];}
Ilahi Charfeddine
fonte
7

iOS13 UISegmentController

Como usar:

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()!)!
    }
}
Jigar Darji
fonte
1
Esta é a única abordagem que funcionou para mim - as imagens de fundo. selectedSegmentTintColor não funcionou por algum motivo.
DenNukem
7

XCODE 11.1 e iOS 13

Com base na resposta de @Jigar Darji, mas uma implementação mais segura.

Primeiro, criamos um inicializador de conveniência disponível:

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

Em seguida, estendemos 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
    }
  }
}
FredFlinstone
fonte
Perfeito! Obrigado!
Senocico Stelian
5

Aqui está minha opinião sobre a resposta de Jonathan. Para Xamarin.iOS (C #), mas com correções para dimensionamento de imagem. Como no comentário de Cœur sobre a resposta de Colin Blake, fiz todas as imagens, exceto a divisória, do tamanho do controle segmentado. O divisor é 1xaltura do segmento.

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;
}
t9mike
fonte
3

Você pode implementar o seguinte método

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

Código de uso

segmentControl.unselectedSegmentTintColor(.white)
segmentControl.selectedSegmentTintColor(.black)
Zain Anjum
fonte
0

Embora as respostas acima sejam ótimas, muitas delas erram na cor do texto dentro do segmento selecionado. Eu criei uma UISegmentedControlsubclasse que você pode usar em dispositivos iOS 13 e pré-iOS 13 e usar a propriedade tintColor como faria em dispositivos pré-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)
        }
    }

Usando o tintColorDidChangemétodo, garantimos que o stylizemétodo será chamado sempre que otintColor propriedade for alterada na visualização do segmento ou em qualquer uma das visualizações subjacentes, que é o comportamento preferido no iOS.

Resultado: insira a descrição da imagem aqui

Adão
fonte
-2

Expandindo um pouco a resposta de Jonathan caso você não queira cantos arredondados

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