Como crio um UILabel com cantos arredondados no iPhone?

Respostas:

229

iOS 3.0 e posterior

O iPhone OS 3.0 e versões posteriores suportam a cornerRadiuspropriedade na CALayerclasse. Toda visualização possui uma CALayerinstância que você pode manipular. Isso significa que você pode obter cantos arredondados em uma linha:

view.layer.cornerRadius = 8;

Você precisará #import <QuartzCore/QuartzCore.h>e vincular a estrutura do QuartzCore para obter acesso aos cabeçalhos e propriedades do CALayer.

Antes do iOS 3.0

Uma maneira de fazer isso, que usei recentemente, é criar uma subclasse UIView que simplesmente desenha um retângulo arredondado e, em seguida, crie o UILabel ou, no meu caso, UITextView, uma sub-visualização dentro dele. Especificamente:

  1. Crie uma UIViewsubclasse e nomeie-a como algo RoundRectView.
  2. Em RoundRectView's drawRect:método, desenhar um caminho em torno dos limites da vista usando chamadas de núcleo de gráficos, como CGContextAddLineToPoint () para as bordas e e CGContextAddArcToPoint () para os cantos arredondados.
  3. Crie uma UILabelinstância e torne-a uma sub-visualização do RoundRectView.
  4. Defina o quadro da etiqueta como alguns pixels inseridos nos limites do RoundRectView. (Por exemplo label.frame = CGRectInset(roundRectView.bounds, 8, 8);)

Você pode colocar o RoundRectView em uma exibição usando o Interface Builder se criar um UIView genérico e depois alterar sua classe usando o inspetor. Você não verá o retângulo até compilar e executar seu aplicativo, mas pelo menos poderá colocar a subvisão e conectá-la a tomadas ou ações, se necessário.

benzado
fonte
1
O view.layer.cornerRadius ainda desenha a visualização inteira (fora da tela quando ativada) e somente na camada CoreAnimation será cortada a visualização. O custo é que isso fará com que qualquer visualização com ela ativada em um UIScrollView reduza o desempenho da rolagem.
Zac Bowling
Usar o cornerRadius dentro de um UIScrollView matará seu desempenho de rolagem? Eu poderia acreditar em você se nós estamos falando de um UITableView, mas uma visão única arredondado canto não vai moer a visão do sistema de desenho a um impasse.
benzado
20
Se você quiser fazer isso no Interface Builder em vez de código, poderá definir um Atributo de Tempo de Execução Definido pelo Usuário com o caminho da chave "layer.cornerRadius" no Identity Inspector.
22412 Chris Chasselli
141

Para dispositivos com iOS 7.1 ou posterior, é necessário adicionar:

yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;
OscarWyck
fonte
3
Defina o raio do canto, mas masksToBounds é lento para rolagem / animação. Se você definir a cor de fundo da camada versus a visualização, isso é suficiente em conjunto com o cornerRadius da camada no 7.1 (onde ele teria parado de funcionar apenas com o cornerRadius).
Aaron Zinman
22

Para o Swift IOS8 em diante, com base na resposta do OScarsWyck:

yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0
VBaarathi
fonte
15
Por favor, não confunda Stack Overflow com traduções das respostas do Objective-C para o Swift, particularmente quando a única alteração nesse caso está sendo alterada YESpara true.
mluisbrown
7
A mudança neste caso é mínima, mas como um ponto geral, as traduções do Objective-C para o Swift são frequentemente muito úteis.
CKP78
1
Que tal editar a resposta original e adicionar a tradução Swift lá?
Marián Černý
11
  1. você tem um UILabelchamado: myLabel.
  2. na importação do arquivo "m" ou "h": #import <QuartzCore/QuartzCore.h>
  3. em seu viewDidLoadescrever esta linha:self.myLabel.layer.cornerRadius = 8;

    • depende de como você deseja, você pode alterar o valor cornerRadius de 8 para outro número :)

Boa sorte

Gabriel
fonte
11

Você pode fazer borda arredondada com largura da borda de qualquer controle da seguinte maneira: -

CALayer * l1 = [lblName layer];
[l1 setMasksToBounds:YES];
[l1 setCornerRadius:5.0];

// You can even add a border
[l1 setBorderWidth:5.0];
[l1 setBorderColor:[[UIColor darkGrayColor] CGColor]];


Basta substituir lblNamecom o seu UILabel.

Nota: - Não se esqueça de importar<QuartzCore/QuartzCore.h>

Piyush Dubey
fonte
7

Eu fiz uma UILabelsubclasse rápida para alcançar esse efeito. Além disso, defino automaticamente a cor do texto para preto ou branco para obter o máximo contraste.

Resultado

bordas arredondadas em cores

Posts SO usados:

Parque infantil

Basta colar isso no iOS Playground:

//: Playground - noun: a place where people can play

import UIKit

class PillLabel : UILabel{

    @IBInspectable var color = UIColor.lightGrayColor()
    @IBInspectable var cornerRadius: CGFloat = 8
    @IBInspectable var labelText: String = "None"
    @IBInspectable var fontSize: CGFloat = 10.5

    // This has to be balanced with the number of spaces prefixed to the text
    let borderWidth: CGFloat = 3

    init(text: String, color: UIColor = UIColor.lightGrayColor()) {
        super.init(frame: CGRectMake(0, 0, 1, 1))
        labelText = text
        self.color = color
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup(){
        // This has to be balanced with the borderWidth property
        text = "  \(labelText)".uppercaseString

        // Credits to https://stackoverflow.com/a/33015915/784318
        layer.borderWidth = borderWidth
        layer.cornerRadius = cornerRadius
        backgroundColor = color
        layer.borderColor = color.CGColor
        layer.masksToBounds = true
        font = UIFont.boldSystemFontOfSize(fontSize)
        textColor = color.contrastColor
        sizeToFit()

        // Credits to https://stackoverflow.com/a/15184257/784318
        frame = CGRectInset(self.frame, -borderWidth, -borderWidth)
    }
}


extension UIColor {
    // Credits to https://stackoverflow.com/a/29044899/784318
    func isLight() -> Bool{
        var green: CGFloat = 0.0, red: CGFloat = 0.0, blue: CGFloat = 0.0, alpha: CGFloat = 0.0
        self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        let brightness = ((red * 299) + (green * 587) + (blue * 114) ) / 1000

        return brightness < 0.5 ? false : true
    }

    var contrastColor: UIColor{
        return self.isLight() ? UIColor.blackColor() : UIColor.whiteColor()
    }
}

var label = PillLabel(text: "yellow", color: .yellowColor())

label = PillLabel(text: "green", color: .greenColor())

label = PillLabel(text: "white", color: .whiteColor())

label = PillLabel(text: "black", color: .blackColor())
Besi
fonte
6

Outro método é colocar um png atrás do UILabel. Tenho exibições com vários rótulos que sobrepõem um único plano de fundo png que possui todo o trabalho artístico dos rótulos individuais.

Alpinista
fonte
6

xCode 7.3.1 iOS 9.3.2

 _siteLabel.layer.masksToBounds = true;
  _siteLabel.layer.cornerRadius = 8;
Ahmed Abdallah
fonte
6

Se você quiser canto arredondado da UI objetos como ( UILabel, UIView, UIButton, UIImageView) por storyboard em seguida, definir clip to boundsverdade e definir User Defined Runtime Attributescaminho chave como layer.cornerRadius, type = Número e valor = 9 (como sua exigência)

Defina o clipe para limites como Definir atributos de tempo de execução definidos pelo usuário como

Nikhlesh Bagdiya
fonte
4
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
    label.text = @"Your String.";
    label.layer.cornerRadius = 8.0;
    [self.view addSubview:label];
Gaurav Gilani
fonte
3

Swift 3

Se você quiser etiqueta arredondada com cor de fundo, além da maioria das outras respostas, também precisará definir layera cor de fundo. Não funciona ao definir a viewcor de fundo.

label.layer.cornerRadius = 8
label.layer.masksToBounds = true
label.layer.backgroundColor = UIColor.lightGray.cgColor

Se você estiver usando o layout automático, desejar algum preenchimento ao redor do rótulo e não desejar definir o tamanho do rótulo manualmente, poderá criar a subclasse UILabel e substituir a intrinsincContentSizepropriedade:

class LabelWithPadding: UILabel {
    override var intrinsicContentSize: CGSize {
        let defaultSize = super.intrinsicContentSize
        return CGSize(width: defaultSize.width + 12, height: defaultSize.height + 8)
    }
}

Para combinar os dois, você também precisará definir label.textAlignment = center, caso contrário, o texto ficará alinhado.

Marián Černý
fonte
2

No Monotouch / Xamarin.iOS, resolvi o mesmo problema assim:

UILabel exampleLabel = new UILabel(new CGRect(0, 0, 100, 50))
        {
            Text = "Hello Monotouch red label"
        };
        exampleLabel.Layer.MasksToBounds = true;
        exampleLabel.Layer.CornerRadius = 8;
        exampleLabel.Layer.BorderColor = UIColor.Red.CGColor;
        exampleLabel.Layer.BorderWidth = 2;
Daniele D.
fonte
2

Funciona perfeitamente no Swift 2.0

    @IBOutlet var theImage: UIImageView! //you can replace this with any UIObject eg: label etc


    override func viewDidLoad() {
        super.viewDidLoad()
//Make sure the width and height are same
        self.theImage.layer.cornerRadius = self.theImage.frame.size.width / 2
        self.theImage.layer.borderWidth = 2.0
        self.theImage.layer.borderColor = UIColor.whiteColor().CGColor
        self.theImage.clipsToBounds = true

    }
Naishta
fonte
2

Você tentou usar o UIButtondo construtor Interface (que possui cantos arredondados) e experimentar as configurações para fazer com que parecesse um rótulo. se tudo o que você deseja é exibir texto estático.

Naren
fonte
2

Funciona bem no Xcode 8.1.2 com Swift 3, testado em agosto de 2017

"cornerRadius" é a propriedade key para definir as arestas arredondadas, onde se você estiver usando o mesmo estilo para todos os rótulos em seu aplicativo, eu recomendaria um método de extensão.

Código:

 // extension Class
extension UILabel {

    // extension user defined Method
    func setRoundEdge() {
        let myGreenColor = (UIColor(red: -0.108958, green: 0.714926, blue: 0.758113, alpha: 1.0))
        //Width of border
        self.layer.borderWidth = 1.0
        //How much the edge to be rounded
        self.layer.cornerRadius = 5.0

        // following properties are optional
        //color for border
        self.layer.borderColor = myGreenColor.cgColor
        //color for text
        self.textColor = UIColor.red
        // Mask the bound
        self.layer.masksToBounds = true
        //clip the pixel contents
        self.clipsToBounds = true
    }
}

Resultado:

insira a descrição da imagem aqui

Por que método de extensão?

Crie um arquivo Swift e adicione o código a seguir, que possui o método Extention à classe "UILabel", onde esse método é definido pelo usuário, mas funcionará para todo o rótulo do seu aplicativo e ajudará a manter a consistência e o código limpo, se você alterar qualquer estilo no futuro requer apenas no método de extensão.

BHUVANESH MOHANKUMAR
fonte
0

Dependendo do que exatamente você está fazendo, você pode criar uma imagem e defini-la como plano de fundo programaticamente.

Steven Mayer
fonte