在iPhone上如何创建圆角UILabel?

154

有没有内置的方法可以创建圆角UILabel? 如果答案是否定的,那么怎样才能创建这样一个对象呢?

16个回答

235

iOS 3.0及以上版本

iPhone OS 3.0 及以上版本支持 CALayer 类的 cornerRadius 属性。每个视图都有一个 CALayer 实例,您可以对其进行操作。这意味着您可以通过一行代码获得圆角:

view.layer.cornerRadius = 8;
您需要#import <QuartzCore/QuartzCore.h> 并链接到QuartzCore框架,以访问CALayer的头文件和属性。
iOS 3.0之前(Before iOS 3.0)
一种方法是创建一个UIView子类,简单地绘制圆角矩形,然后将UILabel或UITextView作为子视图放置在其中。具体步骤如下:
1. 创建一个UIView子类,命名为RoundRectView。 2. 在RoundRectView的drawRect:方法中,使用核心图形调用,如CGContextAddLineToPoint()来绘制路径,绘制出视图边界周围的路径,并使用CGContextAddArcToPoint()绘制圆角。 3. 创建一个UILabel实例,并将其设置为RoundRectView的子视图。 4. 将标签的frame设置为比RoundRectView的bounds稍微缩进一些像素。(例如:label.frame = CGRectInset(roundRectView.bounds, 8, 8);)
您可以在Interface Builder中使用RoundRectView将其放置在视图上,如果创建了一个通用的UIView,然后使用检查器更改其类别,直到编译和运行应用程序,您才能看到该矩形,但至少您可以放置子视图并连接到所需的插座或操作。

1
view.layer.cornerRadius仍然会绘制整个视图(在启用时会绘制到屏幕外),只有在CoreAnimation层级上才会裁剪您的视图。代价是,如果在UIScrollView中放置任何启用了此属性的视图,将会降低滚动性能。 - Zac Bowling
在UIScrollView中使用cornerRadius会严重影响滚动性能?如果我们谈论的是UITableView,我可能会相信你,但单个带圆角的视图不会使视图绘制系统停顿。 - benzado
20
如果你想在界面构建器中完成而不是代码中,你可以在“Identity Inspector”中设置一个带有关键路径“layer.cornerRadius”的用户定义运行时属性。 - Chris Vasselli

147

对于iOS 7.1或更高版本的设备,您需要添加:

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

3
设置圆角半径时,但在滚动/动画过程中masksToBounds操作会比较慢。如果在7.1版本上设置图层的背景颜色与圆角半径,就足以替代仅使用圆角半径(在这种情况下,masksToBounds操作会停止工作)。请注意不要改变原意。 - Aaron Zinman

25

根据 OScarsWyck 的回答,适用于 Swift IOS8 及以上版本:

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

18
请勿在Stack Overflow上将Objective-C答案翻译成Swift,尤其是当唯一的更改是将“YES”更改为“true”时。请注意保持内容简洁易懂,不要添加无关信息。 - mluisbrown
14
在这种情况下,变化很小,但通常来说,从Objective-C翻译成Swift非常有用。 - CKP78
1
把原来的答案编辑一下,加上 Swift 的翻译怎么样? - Marián Černý

11
  1. 你有一个名为:myLabelUILabel
  2. 在你的 "m" 或 "h" 文件中引入:#import <QuartzCore/QuartzCore.h>
  3. 在你的 viewDidLoad 中写入这行代码:self.myLabel.layer.cornerRadius = 8;

    • 取决于你想要的,你可以将 cornerRadius 值从8改为其他数字 :)

祝好运


11

您可以通过以下方式使任何控件的边框变为圆角:

border-radius: 50%;

其中,边框宽度可以根据需要进行调整。

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


只需用您的UILabel替换lblName即可。

注意:不要忘记导入<QuartzCore/QuartzCore.h>


10

Swift 3

如果你想要一个带背景颜色的圆角标签,除了其他答案之外,你还需要设置layer的背景颜色。在设置view的背景颜色时是不起作用的。

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

如果您正在使用自动布局,希望在标签周围设置一些填充,并且不想手动设置标签的大小,那么您可以创建一个UILabel子类并覆盖intrinsicContentSize属性:

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

为了将两者结合起来,您还需要设置 label.textAlignment = center,否则文本将左对齐。

9
如果您想在Storyboard中为UI对象(例如UILabelUIViewUIButtonUIImageView)设置圆角,则需要将clip to bounds设置为true,并将User Defined Runtime Attributes的Key path设置为layer.cornerRadius,类型为数字,值为9(根据您的需求而定)。
请参考下图:Set clip to bounds as Set User Defined Runtime Attributes as

9
我制作了一个快速的UILabel子类来实现这个效果。此外,我自动将文本颜色设置为黑色或白色,以获得最大对比度。

结果

colors-rounded-borders

使用的SO帖子:

Playground

只需将此粘贴到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://dev59.com/AXE95IYBdhLWcg3wbtfO#33015915
        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://dev59.com/NWUp5IYBdhLWcg3wkITF#15184257
        frame = CGRectInset(self.frame, -borderWidth, -borderWidth)
    }
}


extension UIColor {
    // Credits to https://dev59.com/bXE85IYBdhLWcg3w_I78#29044899
    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())

8

xCode 7.3.1 iOS 9.3.2

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

6

另一种方法是在UILabel后面放置一个png。我有一些视图,其中有几个标签覆盖在单个背景png上,该png具有各个标签的所有艺术品。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接