Wie erstelle ich ein UILabel mit runden Ecken auf dem iPhone?

150

Gibt es einen eingebauten Weg, um UILabels mit runden Ecken zu erstellen? Wenn die Antwort nein ist, wie würde man vorgehen, um ein solches Objekt zu erstellen?

Newtonapple
quelle

Antworten:

229

iOS 3.0 und höher

iPhone OS 3.0 und höher unterstützt die cornerRadiusEigenschaft für die CALayerKlasse. Jede Ansicht verfügt über eine CALayerInstanz, die Sie bearbeiten können. Dies bedeutet, dass Sie abgerundete Ecken in einer Linie erhalten können:

view.layer.cornerRadius = 8;

Du wirst brauchen #import <QuartzCore/QuartzCore.h> das QuartzCore-Framework verweisen, um Zugriff auf die Header und Eigenschaften von CALayer zu erhalten.

Vor iOS 3.0

Eine Möglichkeit, die ich kürzlich verwendet habe, besteht darin, eine UIView-Unterklasse zu erstellen, die einfach ein abgerundetes Rechteck zeichnet, und dann das UILabel oder in meinem Fall UITextView zu einer darin enthaltenen Unteransicht zu machen. Speziell:

  1. Erstellen Sie eine UIViewUnterklasse und nennen Sie sie so RoundRectView.
  2. Zeichnen Sie in RoundRectView's drawRect:Methode einen Pfad um die Grenzen der Ansicht, indem Sie Core Graphics-Aufrufe wie CGContextAddLineToPoint () für die Kanten und CGContextAddArcToPoint () für die abgerundeten Ecken verwenden.
  3. Ein ... kreieren UILabel Instanz und machen Sie sie zu einer Unteransicht von RoundRectView.
  4. Stellen Sie den Rahmen des Etiketts so ein, dass er einige Pixel von den Grenzen des RoundRectView entfernt ist. (Zum Beispiel label.frame = CGRectInset(roundRectView.bounds, 8, 8);)

Sie können RoundRectView mit Interface Builder in einer Ansicht platzieren, wenn Sie eine generische UIView erstellen und deren Klasse dann mit dem Inspektor ändern. Sie werden das Rechteck erst sehen, wenn Sie Ihre App kompilieren und ausführen, aber zumindest können Sie die Unteransicht platzieren und sie bei Bedarf mit Outlets oder Aktionen verbinden.

Benzado
quelle
1
view.layer.cornerRadius zeichnet weiterhin die gesamte Ansicht (stattdessen außerhalb des Bildschirms, wenn diese aktiviert ist) und nur auf der CoreAnimation-Ebene wird Ihre Ansicht abgeschnitten. Die Kosten sind, dass dadurch das Aktivieren einer Ansicht in einer UIScrollView beeinträchtigt wird und Ihre Bildlaufleistung beeinträchtigt wird.
Zac Bowling
Unter Verwendung innerhalb eines UIScrollView corner wird töten Ihre Scrollen Leistung? Ich könnte Ihnen glauben, wenn es sich um eine UITableView handelt, aber eine einzelne Ansicht mit abgerundeten Ecken wird das Ansichtszeichnungssystem nicht zum Stillstand bringen.
Benzado
20
Wenn Sie dies im Interface Builder anstelle von Code tun möchten, können Sie im Identitätsinspektor ein benutzerdefiniertes Laufzeitattribut mit dem Schlüsselpfad "layer.cornerRadius" festlegen.
Chris Vasselli
140

Für Geräte mit iOS 7.1 oder höher müssen Sie Folgendes hinzufügen:

yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;
OscarWyck
quelle
3
Stellen Sie den Eckenradius ein, aber masksToBounds ist für das Scrollen / Animieren langsam. Wenn Sie die Hintergrundfarbe der Ebene gegenüber der Ansicht festlegen, reicht dies in Verbindung mit dem CornerRadius der Ebene in 7.1 aus (wo es nicht mehr nur mit CornerRadius funktioniert hätte).
Aaron Zinman
22

Ab Swift IOS8 basierend auf OScarsWyck Antwort:

yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0
VBaarathi
quelle
15
Bitte Krempel nicht auf Stack - Überlauf mit Übersetzungen von Objective-C Antworten in Swift, insbesondere dann , wenn die einzige Änderung in diesem Fall ändert sich YESzu true.
mluisbrown
7
Die Änderung in diesem Fall ist minimal, aber im Allgemeinen sind Übersetzungen von Objective-C in Swift oft sehr nützlich.
CKP78
Wie wäre es, wenn Sie die ursprüngliche Antwort bearbeiten und dort eine Swift-Übersetzung hinzufügen?
Marián Černý
11
  1. Sie haben einen UILabelAnruf : myLabel.
  2. in Ihre "m" oder "h" Datei importieren: #import <QuartzCore/QuartzCore.h>
  3. in Ihrer viewDidLoadSchreib dieser Zeile:self.myLabel.layer.cornerRadius = 8;

    • hängt davon ab, wie Sie möchten, können Sie den CornerRadius-Wert von 8 auf eine andere Zahl ändern :)

Viel Glück

Gabriel
quelle
11

Sie können einen gerundeten Rand mit der Breite des Randes eines beliebigen Steuerelements folgendermaßen erstellen: -

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


Ersetzen lblNameSie einfach durch Ihre UILabel.

Hinweis: - Vergessen Sie nicht zu importieren<QuartzCore/QuartzCore.h>

Piyush Dubey
quelle
7

Ich habe eine schnelle UILabelUnterklasse erstellt, um diesen Effekt zu erzielen. Außerdem habe ich die Textfarbe für maximalen Kontrast automatisch auf Schwarz oder Weiß eingestellt.

Ergebnis

Farben-abgerundete Ränder

Gebrauchte SO-Beiträge:

Spielplatz

Fügen Sie dies einfach in einen iOS-Spielplatz ein:

//: 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
quelle
6

Eine andere Methode besteht darin, ein PNG hinter dem UILabel zu platzieren. Ich habe Ansichten mit mehreren Beschriftungen, die eine einzelne Hintergrund-PNG überlagern, die alle Grafiken für die einzelnen Beschriftungen enthält.

Alpinista
quelle
6

xCode 7.3.1 iOS 9.3.2

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

Wenn Sie UI abgerundete Ecke wollen Objekte wie ( UILabel, UIView, UIButton, UIImageView) von Storyboard dann gesetzt clip to boundswahr und stellen User Defined Runtime AttributesSchlüsselpfade als layer.cornerRadiusTyp = Anzahl und Wert = 9 (als Ihre Anforderung)

Clip auf Grenzen setzen als Legen Sie benutzerdefinierte Laufzeitattribute als fest

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

Swift 3

Wenn Sie ein abgerundetes Etikett mit Hintergrundfarbe wünschen, müssen Sie zusätzlich zu den meisten anderen Antworten auch die layerHintergrundfarbe festlegen . Es funktioniert nicht beim Einstellen der viewHintergrundfarbe.

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

Wenn Sie das automatische Layout verwenden, das Etikett auffüllen und die Größe des Etiketts nicht manuell festlegen möchten, können Sie eine UILabel-Unterklasse erstellen und die intrinsincContentSizeEigenschaft überschreiben :

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

Um die beiden zu kombinieren, müssen Sie auch festlegen label.textAlignment = center, sonst würde der Text linksbündig bleiben.

Marián Černý
quelle
2

In Monotouch / Xamarin.iOS habe ich das gleiche Problem wie folgt gelöst:

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

Funktioniert perfekt 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

    }
Naishta
quelle
2

Haben Sie versucht, den UIButtonBuilder aus dem Interface-Builder (mit abgerundeten Ecken) zu verwenden und mit den Einstellungen zu experimentieren, damit er wie eine Beschriftung aussieht? Wenn Sie nur statischen Text anzeigen möchten.

Naren
quelle
2

Funktioniert gut in Xcode 8.1.2 mit Swift 3, getestet im AUGUST 2017

"CornerRadius" ist die Schlüsseleigenschaft zum Festlegen der abgerundeten Kanten. Wenn Sie für alle Beschriftungen in Ihrer Anwendung denselben Stil verwenden, würde ich eine Erweiterungsmethode empfehlen.

Code:

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

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Warum Verlängerungsmethode?

Erstellen Sie eine Swift-Datei und fügen Sie den folgenden Code mit der Extention-Methode zur "UILabel" -Klasse hinzu. Diese Methode ist benutzerdefiniert, funktioniert jedoch für alle Labels in Ihrer Anwendung und trägt zur Aufrechterhaltung der Konsistenz und des sauberen Codes bei, wenn Sie dies tun Ändern Sie einen Stil in Zukunft nur in der Erweiterungsmethode.

BHUVANESH MOHANKUMAR
quelle
0

Je nachdem, was genau Sie tun, können Sie ein Bild erstellen und es programmgesteuert als Hintergrund festlegen.

Steven Mayer
quelle