Jak utworzyć zaokrąglony UILabel na iPhonie?

Odpowiedzi:

229

iOS 3.0 i nowsze

iPhone OS 3.0 i nowsze obsługują cornerRadiuswłaściwość w CALayerklasie. Każdy widok ma CALayerinstancję, którą możesz manipulować. Oznacza to, że możesz uzyskać zaokrąglone rogi w jednej linii:

view.layer.cornerRadius = 8;

Będziesz musiał #import <QuartzCore/QuartzCore.h>połączyć się ze strukturą QuartzCore, aby uzyskać dostęp do nagłówków i właściwości CALayera.

Przed iOS 3.0

Jednym ze sposobów, z którego ostatnio korzystałem, jest utworzenie podklasy UIView, która po prostu rysuje zaokrąglony prostokąt, a następnie tworzy UILabel lub, w moim przypadku, UITextView, podwidok wewnątrz niej. Konkretnie:

  1. Utwórz UIViewpodklasę i nazwij ją podobną do RoundRectView.
  2. In RoundRectView's drawRect:narysuj ścieżkę wokół granic widoku, używając wywołań Core Graphics, takich jak CGContextAddLineToPoint () dla krawędzi i CGContextAddArcToPoint () dla zaokrąglonych rogów.
  3. Utwórz UILabelwystąpienie i ustaw go jako podwidok RoundRectView.
  4. Ustaw ramkę etykiety tak, aby była wstawiona kilka pikseli w granicach RoundRectView. (Na przykład label.frame = CGRectInset(roundRectView.bounds, 8, 8);)

Możesz umieścić RoundRectView w widoku za pomocą Interface Builder, jeśli utworzysz ogólny UIView, a następnie zmienisz jego klasę za pomocą inspektora. Nie zobaczysz prostokąta, dopóki nie skompilujesz i nie uruchomisz aplikacji, ale przynajmniej będziesz w stanie umieścić widok podrzędny i połączyć go z gniazdami lub akcjami w razie potrzeby.

benzado
źródło
1
view.layer.cornerRadius nadal rysuje cały widok (zamiast ekranu, gdy jest włączony) i tylko w warstwie CoreAnimation przycina widok. Koszt jest taki, że spowoduje to, że umieszczenie dowolnego widoku z włączonym widokiem w UIScrollView, zabije wydajność przewijania.
Zac Bowling
Korzystanie cornerRadius wewnątrz UIScrollView będzie zabić wydajność przewijania? I może ci wierzyć, jeśli mówimy o UITableView, ale pojedynczy widok zaokrąglony narożnik-nie zamierza szlifować widok systemu rysunek do zatrzymania.
benzado
20
Jeśli chcesz to zrobić w programie Interface Builder zamiast w kodzie, możesz ustawić atrybut wykonawczy zdefiniowany przez użytkownika ze ścieżką klucza „layer.cornerRadius” w Inspektorze tożsamości.
Chris Vasselli
141

W przypadku urządzeń z iOS 7.1 lub nowszym musisz dodać:

yourUILabel.layer.masksToBounds = YES;
yourUILabel.layer.cornerRadius = 8.0;
OscarWyck
źródło
3
Ustaw promień narożnika, ale maska ​​masksToBounds działa wolno podczas przewijania / animacji. Jeśli ustawisz kolor tła warstwy w porównaniu z widokiem, to wystarczy w połączeniu z rogiem warstwy na 7.1 (gdzie przestałby działać tylko z cornerRadius).
Aaron Zinman
22

Dla Swift IOS8 i nowszych w oparciu o odpowiedź OScarsWyck:

yourUILabel.layer.masksToBounds = true
yourUILabel.layer.cornerRadius = 8.0
VBaarathi
źródło
15
Nie zaśmiecaj Stack Overflow tłumaczeniami odpowiedzi Objective-C na Swift, zwłaszcza gdy jedyną zmianą w tym przypadku jest zmiana YESna true.
mluisbrown
7
Zmiana w tym przypadku jest minimalna, ale jako ogólne tłumaczenie punktów z Objective-C na Swift jest często bardzo przydatne.
CKP78
1
Co powiesz na edycję oryginalnej odpowiedzi i dodanie tam tłumaczenia Szybkiego?
Marián Černý
11
  1. ty mieć UILabelo nazwie: myLabel.
  2. w imporcie pliku „m” lub „h”: #import <QuartzCore/QuartzCore.h>
  3. w swoim viewDidLoadnapisz tę linię:self.myLabel.layer.cornerRadius = 8;

    • zależy od tego, jak chcesz, możesz zmienić wartość cornerRadius z 8 na inną liczbę :)

Powodzenia

Gabriel
źródło
11

Możesz zrobić zaokrąglone obramowanie z szerokością obramowania dowolnej kontroli w ten sposób: -

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


Po prostu wymień lblNamena UILabel.

Uwaga: - Nie zapomnij zaimportować<QuartzCore/QuartzCore.h>

Piyush Dubey
źródło
7

Stworzyłem szybką UILabelpodklasę, aby osiągnąć ten efekt. Ponadto automatycznie ustawiam kolor tekstu na czarny lub biały, aby uzyskać maksymalny kontrast.

Wynik

kolory-zaokrąglone-granice

Używane słupki SO:

Plac zabaw

Po prostu wklej to do Playground 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())
Besi
źródło
6

Inną metodą jest umieszczenie png za UILabel. Mam widoki z kilkoma etykietami, które nakładają się na pojedynczy plik PNG w tle, zawierający całą grafikę dla poszczególnych etykiet.

Alpinista
źródło
6

xCode 7.3.1 iOS 9.3.2

 _siteLabel.layer.masksToBounds = true;
  _siteLabel.layer.cornerRadius = 8;
Ahmed Abdallah
źródło
6

Jeśli chcesz zaokrąglony narożnik UI obiektów jak ( UILabel, UIView, UIButton, UIImageView) przez ujęć następnie ustawić clip to boundsprawdziwe i ustawić User Defined Runtime Attributesścieżkę klucza jako layer.cornerRadiustype = liczba i wartość = 9 (jako wymóg)

Ustaw klip do granic jako Ustaw atrybuty środowiska wykonawczego zdefiniowane przez użytkownika jako

Nikhlesh Bagdiya
źródło
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
źródło
3

Szybki 3

Jeśli chcesz mieć zaokrągloną etykietę z kolorem tła, oprócz większości innych odpowiedzi musisz również ustawić layerkolor tła. Nie działa przy ustawianiu viewkoloru tła.

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

Jeśli korzystasz z automatycznego układu, potrzebujesz dopełnienia wokół etykiety i nie chcesz ręcznie ustawiać rozmiaru etykiety, możesz utworzyć podklasę UILabel i nadpisać intrinsincContentSizewłaściwość:

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

Aby połączyć te dwa elementy, musisz również ustawić label.textAlignment = center, w przeciwnym razie tekst zostanie wyrównany do lewej.

Marián Černý
źródło
2

W Monotouch / Xamarin.iOS rozwiązałem ten sam problem:

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.
źródło
2

Działa idealnie w 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
źródło
2

Czy próbowałeś użyć UIButtonkreatora interfejsu (który ma zaokrąglone rogi) i eksperymentowałeś z ustawieniami, aby wyglądał jak etykieta? jeśli chcesz tylko wyświetlać w nim tekst statyczny.

Naren
źródło
2

Działa dobrze w Xcode 8.1.2 ze Swift 3, testowane w sierpniu 2017 r

"cornerRadius" jest kluczową właściwością do ustawiania zaokrąglonych krawędzi, gdzie jeśli używasz tego samego stylu dla wszystkich etykiet w swojej aplikacji, poleciłbym metodę rozszerzenia.

Kod:

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

Wynik:

wprowadź opis obrazu tutaj

Dlaczego metoda przedłużania?

Utwórz plik Swift i dodaj następujący kod, który zawiera metodę Extention do klasy „UILabel”, gdzie ta metoda jest zdefiniowana przez użytkownika, ale będzie działać dla wszystkich etykiet w Twojej aplikacji i pomoże zachować spójność i czysty kod, jeśli zmiana dowolnego stylu w przyszłości wymaga tylko w metodzie rozszerzenia.

BHUVANESH MOHANKUMAR
źródło
0

W zależności od tego, co dokładnie robisz, możesz programowo utworzyć obraz i ustawić go jako tło.

Steven Mayer
źródło