Làm cách nào để tạo một UILabel góc tròn trên iPhone?


Câu trả lời:


229

iOS 3.0 trở lên

iPhone OS 3.0 trở lên hỗ trợ cornerRadiustài sản trên CALayerlớp. Mỗi khung nhìn có một CALayerví dụ mà bạn có thể thao tác. Điều này có nghĩa là bạn có thể có được các góc tròn trong một dòng:

view.layer.cornerRadius = 8;

Bạn sẽ cần #import <QuartzCore/QuartzCore.h>và liên kết với khung QuartzCore để có quyền truy cập vào các tiêu đề và thuộc tính của CALay.

Trước iOS 3.0

Một cách để làm điều đó, mà tôi đã sử dụng gần đây, là tạo một lớp con UIView chỉ đơn giản là vẽ một hình chữ nhật tròn, sau đó tạo UILabel hoặc, trong trường hợp của tôi, UITextView, một khung nhìn phụ bên trong nó. Đặc biệt:

  1. Tạo một UIViewlớp con và đặt tên nó giống như RoundRectView.
  2. Trong RoundRectView's drawRect:phương pháp, vẽ một đường xung quanh bờ cõi của các quan điểm sử dụng cuộc gọi lõi đồ họa như CGContextAddLineToPoint () cho các cạnh và và CGContextAddArcToPoint () cho các góc bo tròn.
  3. Tạo một UILabelthể hiện và biến nó thành một khung nhìn phụ của RoundRectView.
  4. Đặt khung của nhãn thành một vài pixel trong giới hạn của RoundRectView. (Ví dụ label.frame = CGRectInset(roundRectView.bounds, 8, 8);:)

Bạn có thể đặt RoundRectView trên chế độ xem bằng Trình tạo giao diện nếu bạn tạo UIView chung và sau đó thay đổi lớp của nó bằng trình kiểm tra. Bạn sẽ không nhìn thấy hình chữ nhật cho đến khi bạn biên dịch và chạy ứng dụng của mình, nhưng ít nhất bạn sẽ có thể đặt chế độ xem phụ và kết nối nó với các cửa hàng hoặc hành động nếu cần.


1
view.layer.cornerRadius vẫn vẽ toàn bộ chế độ xem (thay vào đó là màn hình tắt khi được bật) và chỉ ở lớp CoreAnimation, nó mới cắt được chế độ xem của bạn. Cái giá phải trả là nó sẽ khiến cho bất kỳ chế độ xem nào được bật trong UIScrollView, giết chết hiệu suất cuộn của bạn.
Zac Bowling

Sử dụng angleRadius bên trong UIScrollView sẽ giết chết hiệu suất cuộn của bạn? Tôi có thể tin bạn nếu chúng ta đang nói về một UITableView, nhưng một chế độ xem một góc tròn sẽ không làm hỏng hệ thống vẽ chế độ xem.
benzado

20
Nếu bạn muốn thực hiện việc này trong Trình tạo giao diện thay vì mã, bạn có thể đặt Thuộc tính thời gian chạy do người dùng xác định với đường dẫn chính "layer.cornerRadius" trong Trình kiểm tra danh tính.
Chris Vasselli

141

Đối với các thiết bị có iOS 7.1 trở lên, bạn cần thêm:

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

3
Đặt bán kính góc nhưng maskToBound chậm để cuộn / hoạt hình. Nếu bạn đặt màu nền của lớp so với chế độ xem đủ kết hợp với angleRadius của lớp trên 7.1 (nơi nó sẽ ngừng hoạt động chỉ với angleRadius).
Aaron Zinman

22

Đối với Swift IOS8 trở đi dựa trên câu trả lời của OScarsWyck:

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

15
Vui lòng không làm lộn xộn Stack Overflow với bản dịch các câu trả lời của Objective-C sang Swift, đặc biệt khi thay đổi duy nhất trong trường hợp này là thay đổi YESthành true.
mluisbrown 30/03/2016

7
Sự thay đổi trong trường hợp này là tối thiểu, nhưng vì một bản dịch điểm chung từ Objective-C sang Swift thường rất hữu ích.
CKP78

1
Làm thế nào về việc chỉnh sửa câu trả lời ban đầu và thêm bản dịch Swift ở đó?
Marián erný

11
  1. bạn có một cuộc UILabelgọi : myLabel.
  2. trong quá trình nhập tệp "m" hoặc "h" của bạn: #import <QuartzCore/QuartzCore.h>
  3. trong viewDidLoaddòng viết của bạn :self.myLabel.layer.cornerRadius = 8;

    • phụ thuộc vào cách bạn muốn, bạn có thể thay đổi giá trị angleRadius từ 8 sang số khác :)

Chúc may mắn


11

Bạn có thể tạo đường viền tròn với chiều rộng đường viền của bất kỳ điều khiển nào theo cách này: -

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


Chỉ cần thay thế lblNamebằng của bạn UILabel.

Lưu ý: - Đừng quên nhập<QuartzCore/QuartzCore.h>


7

Tôi đã thực hiện một UILabellớp con nhanh chóng để đạt được hiệu ứng này. Ngoài ra, tôi tự động đặt màu văn bản thành đen hoặc trắng để có độ tương phản tối đa.

Kết quả

viền tròn màu

Bài viết SO đã qua sử dụng:

Sân chơi

Chỉ cần dán cái này vào Sân chơi 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

Một phương pháp khác là đặt một png phía sau UILabel. Tôi có chế độ xem với một số nhãn bao phủ một png nền duy nhất có tất cả các tác phẩm nghệ thuật cho các nhãn riêng lẻ.


6

xCode 7.3.1 iOS 9.3.2

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

6

Nếu bạn muốn làm tròn góc của giao diện người dùng các đối tượng tương tự ( UILabel, UIView, UIButton, UIImageView) bởi kịch bản sau đó thiết lập clip to boundsđúng và thiết lập User Defined Runtime Attributescon đường chính như layer.cornerRadius, type = Số lượng và giá trị = 9 (theo yêu cầu của bạn)

Đặt clip thành giới hạn là Đặt thuộc tính thời gian chạy do người dùng xác định là


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

Nếu bạn muốn nhãn tròn với màu nền, ngoài hầu hết các câu trả lời khác, bạn cũng cần đặt layermàu nền của nó. Nó không hoạt động khi thiết lập viewmàu nền.

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

Nếu bạn đang sử dụng bố cục tự động, muốn có một số phần đệm xung quanh nhãn và không muốn đặt kích thước của nhãn theo cách thủ công, bạn có thể tạo thuộc tính lớp con và ghi đè UILabel intrinsincContentSize:

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

Để kết hợp cả hai bạn cũng sẽ cần phải thiết lập label.textAlignment = center, nếu không văn bản sẽ được căn trái.


2

Trong Monotouch / Xamarin.iOS tôi đã giải quyết vấn đề tương tự như thế này:

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

Hoạt động hoàn hảo trong 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

Bạn đã thử sử dụng trình UIButtonxây dựng Giao diện (có các góc được làm tròn) và thử nghiệm các cài đặt để làm cho nó trông giống như một nhãn. nếu tất cả những gì bạn muốn là hiển thị văn bản tĩnh bên trong.


2

Hoạt động tốt trong Xcode 8.1.2 với Swift 3, được thử nghiệm trong tháng 8 năm 2017

"angleRadius" là thuộc tính chính để đặt các cạnh tròn, trong đó nếu bạn đang sử dụng cùng một kiểu cho tất cả các nhãn trong ứng dụng của mình, tôi sẽ khuyên bạn nên sử dụng phương pháp mở rộng.

Mã số:

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

Đầu ra:

nhập mô tả hình ảnh ở đây

Tại sao phương pháp mở rộng?

Tạo một tệp Swift và thêm mã sau, có phương thức Gia hạn vào lớp "UILabel", trong đó phương thức này do người dùng xác định nhưng sẽ hoạt động cho tất cả các nhãn trong ứng dụng của bạn và sẽ giúp duy trì tính nhất quán và mã sạch, nếu bạn thay đổi bất kỳ phong cách nào trong tương lai chỉ yêu cầu trong phương pháp mở rộng.


0

Tùy thuộc vào chính xác những gì bạn đang làm, bạn có thể tạo một hình ảnh và đặt nó làm nền theo chương trình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.