¿Cómo creo un UILabel acorralado redondo en el iPhone?

Respuestas:

229

iOS 3.0 y posterior

iPhone OS 3.0 y posterior admite la cornerRadiuspropiedad en la CALayerclase. Cada vista tiene una CALayerinstancia que puede manipular. Esto significa que puede obtener esquinas redondeadas en una línea:

view.layer.cornerRadius = 8;

Necesitará #import <QuartzCore/QuartzCore.h>y vincular al marco de QuartzCore para obtener acceso a los encabezados y propiedades de CALayer.

Antes de iOS 3.0

Una forma de hacerlo, que utilicé recientemente, es crear una subclase de UIView que simplemente dibuje un rectángulo redondeado, y luego hacer UILabel o, en mi caso, UITextView, una subvista dentro de él. Específicamente:

  1. Cree una UIViewsubclase y asígnele un nombre RoundRectView.
  2. En RoundRectViewel drawRect:método, dibuje una ruta alrededor de los límites de la vista utilizando llamadas de Core Graphics como CGContextAddLineToPoint () para los bordes y CGContextAddArcToPoint () para las esquinas redondeadas.
  3. Cree una UILabelinstancia y conviértala en una subvista de RoundRectView.
  4. Establezca el marco de la etiqueta en unos pocos píxeles insertados en los límites de RoundRectView. (Por ejemplo label.frame = CGRectInset(roundRectView.bounds, 8, 8);)

Puede colocar RoundRectView en una vista usando Interface Builder si crea una UIView genérica y luego cambia su clase usando el inspector. No verá el rectángulo hasta que compile y ejecute su aplicación, pero al menos podrá colocar la subvista y conectarla a salidas o acciones si es necesario.

benzado
fuente
1
view.layer.cornerRadius todavía dibuja toda la vista (fuera de la pantalla cuando está habilitada) y solo en la capa CoreAnimation recortará su vista. El costo es que hará que poner cualquier vista con él habilitado en UIScrollView, mate su rendimiento de desplazamiento.
Zac Bowling
¿Usar cornerRadius dentro de un UIScrollView matará su rendimiento de desplazamiento? Yo podría creer que si estamos hablando de un UITableView, pero una única vista esquinas redondeadas no se va a moler la vista del sistema de dibujo a un alto.
benzado
20
Si desea hacer esto en Interface Builder en lugar de código, puede establecer un Atributo de tiempo de ejecución definido por el usuario con la ruta clave "layer.cornerRadius" en el Inspector de identidad.
Chris Vasselli
141

Para dispositivos con iOS 7.1 o posterior, debe agregar:

yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;
OscarWyck
fuente
3
Establezca el radio de la esquina pero masksToBounds es lento para el desplazamiento / animación. Si establece el color de fondo de la capa frente a la vista, es suficiente en combinación con el cornerRadius de la capa en 7.1 (donde habría dejado de funcionar solo con cornerRadius).
Aaron Zinman
22

Para Swift IOS8 en adelante basado en la respuesta OScarsWyck:

yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0
VBaarathi
fuente
15
No desordenes Stack Overflow con traducciones de respuestas de Objective-C a Swift, particularmente cuando el único cambio en este caso es cambiar YESa true.
mluisbrown
77
El cambio en este caso es mínimo, pero como un punto general, las traducciones de Objective-C a Swift son a menudo muy útiles.
CKP78
1
¿Qué tal editar la respuesta original y agregar una traducción rápida allí?
Marián Černý
11
  1. tienes un UILabelllamado:myLabel .
  2. en su importación de archivos "m" o "h": #import <QuartzCore/QuartzCore.h>
  3. en tu viewDidLoadescribe esta línea:self.myLabel.layer.cornerRadius = 8;

    • depende de cómo desee puede cambiar el valor de cornerRadius de 8 a otro número :)

Buena suerte

Gabriel
fuente
11

Puede hacer un borde redondeado con ancho de borde de cualquier control de esta manera: -

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


Simplemente reemplace lblNamecon su UILabel.

Nota: - No olvides importar<QuartzCore/QuartzCore.h>

Piyush Dubey
fuente
7

Hice una UILabelsubclase rápida para lograr este efecto. Además, configuro automáticamente el color del texto en blanco o negro para obtener el máximo contraste.

Resultado

bordes redondeados de colores

Postes SO usados:

Patio de recreo

Solo pegue esto en un 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
fuente
6

Otro método es colocar un png detrás de UILabel. Tengo vistas con varias etiquetas que superponen un solo fondo png que tiene todas las ilustraciones para las etiquetas individuales.

Alpinista
fuente
6

xCode 7.3.1 iOS 9.3.2

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

Si quieres esquina redondeada de la interfaz de usuario como objetos ( UILabel, UIView, UIButton, UIImageView) por el guión gráfico a continuación, establecer clip to boundsla verdadera y establecer User Defined Runtime Attributesruta de la clave como layer.cornerRadius, escriba = Número y valor = 9 (como su requisito)

Establecer clip a límites como Establecer los atributos de tiempo de ejecución definidos por el usuario como

Nikhlesh Bagdiya
fuente
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
fuente
3

Swift 3

Si desea una etiqueta redondeada con color de fondo, además de la mayoría de las otras respuestas, también debe establecer layerel color de fondo. No funciona al configurar el viewcolor de fondo.

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

Si está utilizando el diseño automático, desea un poco de relleno alrededor de la etiqueta y no desea establecer el tamaño de la etiqueta manualmente, puede crear la subclase UILabel y anular la intrinsincContentSizepropiedad:

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

Para combinar los dos, también deberá configurarlo label.textAlignment = center; de lo contrario, el texto quedaría alineado.

Marián Černý
fuente
2

En Monotouch / Xamarin.iOS resolví el mismo problema como este:

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.
fuente
2

Funciona perfecto en 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
fuente
2

¿Intentó usar el UIButtongenerador de interfaces (que tiene esquinas redondeadas) y experimentó con la configuración para que parezca una etiqueta. si todo lo que quieres es mostrar texto estático dentro.

Naren
fuente
2

Funciona bien en Xcode 8.1.2 con Swift 3, probado durante AGOSTO 2017

"cornerRadius" es la propiedad clave para establecer los bordes redondeados, donde si está utilizando el mismo estilo para todas las etiquetas en su aplicación, recomendaría un método de extensión.

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

Salida:

ingrese la descripción de la imagen aquí

¿Por qué método de extensión?

Cree un archivo Swift y agregue el siguiente código, que tiene el método Extention a la clase "UILabel", donde este método está definido por el usuario pero funcionará para toda la etiqueta de su aplicación y ayudará a mantener la coherencia y limpiar el código, si usted cambiar cualquier estilo en el futuro solo requiere en el método de extensión.

BHUVANESH MOHANKUMAR
fuente
0

Dependiendo de lo que esté haciendo exactamente, podría hacer una imagen y establecerla como fondo programáticamente.

Steven Mayer
fuente