Come posso creare un UILabel con angoli arrotondati su iPhone?


Risposte:


229

iOS 3.0 e versioni successive

iPhone OS 3.0 e versioni successive supporta la cornerRadiusproprietà della CALayerclasse. Ogni vista ha CALayerun'istanza che puoi manipolare. Ciò significa che puoi ottenere gli angoli arrotondati in una riga:

view.layer.cornerRadius = 8;

Avrai bisogno di #import <QuartzCore/QuartzCore.h> e collegarsi al framework QuartzCore per accedere alle intestazioni e alle proprietà di CALayer.

Prima di iOS 3.0

Un modo per farlo, che ho usato di recente, è creare una sottoclasse UIView che disegna semplicemente un rettangolo arrotondato e quindi trasforma UILabel o, nel mio caso, UITextView, una sottoview al suo interno. In particolare:

  1. Crea una UIViewsottoclasse e chiamala come qualcosa del genereRoundRectView .
  2. In RoundRectView'sdrawRect: metodo, disegnare un percorso attorno ai confini della vista utilizzando chiamate core grafico come CGContextAddLineToPoint () per i bordi e CGContextAddArcToPoint e () per gli angoli arrotondati.
  3. Creare un UILabel un'istanza e rendila una sottoview di RoundRectView.
  4. Imposta la cornice dell'etichetta in modo che sia un inserto di pochi pixel dei limiti di RoundRectView. (Ad esempio, label.frame = CGRectInset(roundRectView.bounds, 8, 8);)

È possibile posizionare RoundRectView su una vista utilizzando Interface Builder se si crea una vista UIV generica e quindi si modifica la sua classe mediante la finestra di ispezione. Non vedrai il rettangolo finché non compili ed esegui la tua app, ma almeno sarai in grado di posizionare la sottoview e collegarla a punti vendita o azioni se necessario.


1
view.layer.cornerRadius disegna comunque l'intera vista (offscreen invece quando è abilitata) e solo al livello CoreAnimation bloccherà la vista. Il costo è che mettere qualsiasi vista con esso abilitato in un UIScrollView, uccidere le prestazioni di scorrimento.
Zac Bowling

L'uso di cornerRadius all'interno di UIScrollView ucciderà le tue prestazioni di scorrimento? Io potrei credere che se stiamo parlando di un UITableView, ma una singola vista con angoli arrotondati non sta per macinare la vista del sistema di disegno per una battuta d'arresto.
benzado,

20
Se si desidera eseguire questa operazione in Interface Builder anziché nel codice, è possibile impostare un attributo di runtime definito dall'utente con il percorso chiave "layer.cornerRadius" in Identity Inspector.
Chris Vasselli,

142

Per i dispositivi con iOS 7.1 o successivo, è necessario aggiungere:

yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;

3
Imposta il raggio dell'angolo ma masksToBounds è lento per lo scorrimento / l'animazione. Se si imposta il colore di sfondo del livello rispetto alla vista, è sufficiente in combinazione con l'angolo del livello Radius su 7.1 (dove avrebbe smesso di funzionare solo con l'angolo Radius).
Aaron Zinman,

22

Per Swift IOS8 in poi basato sulla risposta OScarsWyck:

yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0

15
Si prega di non ingombrare Stack Overflow con le traduzioni delle risposte Objective-C in Swift, in particolare quando l'unica modifica in questo caso sta cambiando YESin true.
Mluisbrown,

7
La modifica in questo caso è minima, ma come punto generale le traduzioni da Objective-C a Swift sono spesso molto utili.
CKP78,

1
Che ne dici di modificare la risposta originale e aggiungere la traduzione Swift lì?
Marián Černý,

11
  1. si dispone di una UILabelchiamata: myLabel.
  2. nell'importazione di file "m" o "h": #import <QuartzCore/QuartzCore.h>
  3. nel tuo viewDidLoadscrivere questa riga:self.myLabel.layer.cornerRadius = 8;

    • dipende da come vuoi puoi cambiare il valore di cornerRadius da 8 ad un altro numero :)

In bocca al lupo


11

È possibile creare un bordo arrotondato con la larghezza del bordo di qualsiasi controllo in questo modo: -

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


Sostituisci semplicemente lblNamecon il tuo UILabel.

Nota: - Non dimenticare di importare<QuartzCore/QuartzCore.h>


7

Ho creato una UILabelsottoclasse rapida per ottenere questo effetto. Inoltre, imposto automaticamente il colore del testo su bianco o nero per il massimo contrasto.

Risultato

colori-arrotondati-borders

Messaggi SO usati:

Terreno di gioco

Basta incollarlo in un parco giochi iOS:

//: 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())

6

Un altro metodo è quello di posizionare un png dietro UILabel. Ho viste con diverse etichette che si sovrappongono a un unico png di sfondo che ha tutte le illustrazioni per le singole etichette.


6

xCode 7.3.1 iOS 9.3.2

 _siteLabel.layer.masksToBounds = true;
  _siteLabel.layer.cornerRadius = 8;

6

Se si vuole angolo arrotondato di UI oggetti come ( UILabel, UIView, UIButton, UIImageView) per storyboard quindi impostare clip to boundsvera e impostare User Defined Runtime Attributesil percorso chiave come layer.cornerRadius, type = Numero e valore = 9 (come vostro requisito)

Imposta la clip sui limiti come Impostare gli attributi di runtime definiti dall'utente come


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

3

Swift 3

Se si desidera un'etichetta arrotondata con il colore di sfondo, oltre alla maggior parte delle altre risposte, è necessario impostare anche layeril colore di sfondo. Non funziona quando si imposta il viewcolore di sfondo.

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

Se si utilizza il layout automatico, si desidera un po 'di riempimento intorno all'etichetta e non si desidera impostare manualmente la dimensione dell'etichetta, è possibile creare la sottoclasse UILabel e sovrascrivere la intrinsincContentSizeproprietà:

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

Per combinare i due dovrai anche impostare label.textAlignment = center, altrimenti il ​​testo verrebbe allineato a sinistra.


2

In Monotouch / Xamarin.iOS ho risolto lo stesso problema in questo modo:

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;

2

Funziona perfettamente in 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

    }

2

Hai provato a usare il UIButtondal builder Interface (che ha gli angoli arrotondati) e hai sperimentato le impostazioni per farlo sembrare un'etichetta. se tutto ciò che vuoi è visualizzare il testo statico all'interno.


2

Funziona bene in Xcode 8.1.2 con Swift 3, testato ad AGOSTO 2017

"cornerRadius" è la proprietà chiave per impostare i bordi arrotondati, dove se si utilizza lo stesso stile per tutte le etichette dell'applicazione, si consiglia un metodo di estensione.

Codice:

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

Produzione:

inserisci qui la descrizione dell'immagine

Perché metodo di estensione?

Crea un file Swift e aggiungi il seguente codice, che ha il metodo Extention alla classe "UILabel", in cui questo metodo è definito dall'utente ma funzionerà per tutte le etichette della tua applicazione e ti aiuterà a mantenere la coerenza e il codice pulito, se cambiare qualsiasi stile in futuro è necessario solo nel metodo di estensione.


0

A seconda di cosa stai esattamente facendo, potresti creare un'immagine e impostarla come sfondo programmaticamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.