how to set UIlabel corner radius for two corners only?

I have a label and I know when I set


label.layer.cornerRadius = 5


this property worked to all corner, but how to do to two corners only, (for example) for upper left and lower left corners?

thanx in advanced.

Accepted Reply

Even for this, you need

label.layer.masksToBounds = true


For what you want, subclass UILabel and then draw the background in a BezierPath.

let path = UIBezierPath

(roundedRect rect: CGRect, byRoundingCorners corners: UIRectCorner, cornerRadii: CGSize)


Here is the example to play with (top left and bottom right are rounded)


@IBDesignable
class SemiRoundLabel: UILabel {
   
    @IBInspectable var radius: Int = 5  // Int needed for IBInspectable
   
    override func draw(_ rect: CGRect) {
       
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .bottomRight], cornerRadii: CGSize(width: radius, height: radius))
        
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = path.cgPath

        self.backgroundColor?.setFill()
        path.fill()
        let textToDraw = self.attributedText!
        textToDraw.draw(in: rect)
    }
}

For topLeft and lowerLeft, replace by

let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .bottomLeft], cornerRadii: CGSize(width: radius, height: radius))


With IBDesignable and IBInspectable, you can see it directly in IB.


You can even set which corners directly in IB, with the default values you want (here top and bottom left)


@IBDesignable
class SemiRoundLabel: UILabel {
   
    @IBInspectable var radius: Int = 5  // Int needed for IBInspectable
    @IBInspectable var borderColor: UIColor = .black
    @IBInspectable var topLeft: Bool = true
    @IBInspectable var topRight: Bool = false
    @IBInspectable var bottomRight: Bool = true
    @IBInspectable var bottomLeft: Bool = false

    override func draw(_ rect: CGRect) {
       
        var corners : UIRectCorner = []
        if topLeft { corners.insert(.topLeft) }
        if topRight { corners.insert(.topRight) }
        if bottomRight { corners.insert(.bottomRight) }
        if bottomLeft { corners.insert(.bottomLeft) }

        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))

        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = path.cgPath
        self.layer.mask = maskLayer

        self.backgroundColor?.setFill()
        path.fill()
        borderColor.setStroke()
        path.stroke()
        let textToDraw = self.attributedText!
        textToDraw.draw(in: rect)
    }
}

Replies

Even for this, you need

label.layer.masksToBounds = true


For what you want, subclass UILabel and then draw the background in a BezierPath.

let path = UIBezierPath

(roundedRect rect: CGRect, byRoundingCorners corners: UIRectCorner, cornerRadii: CGSize)


Here is the example to play with (top left and bottom right are rounded)


@IBDesignable
class SemiRoundLabel: UILabel {
   
    @IBInspectable var radius: Int = 5  // Int needed for IBInspectable
   
    override func draw(_ rect: CGRect) {
       
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .bottomRight], cornerRadii: CGSize(width: radius, height: radius))
        
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = path.cgPath

        self.backgroundColor?.setFill()
        path.fill()
        let textToDraw = self.attributedText!
        textToDraw.draw(in: rect)
    }
}

For topLeft and lowerLeft, replace by

let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .bottomLeft], cornerRadii: CGSize(width: radius, height: radius))


With IBDesignable and IBInspectable, you can see it directly in IB.


You can even set which corners directly in IB, with the default values you want (here top and bottom left)


@IBDesignable
class SemiRoundLabel: UILabel {
   
    @IBInspectable var radius: Int = 5  // Int needed for IBInspectable
    @IBInspectable var borderColor: UIColor = .black
    @IBInspectable var topLeft: Bool = true
    @IBInspectable var topRight: Bool = false
    @IBInspectable var bottomRight: Bool = true
    @IBInspectable var bottomLeft: Bool = false

    override func draw(_ rect: CGRect) {
       
        var corners : UIRectCorner = []
        if topLeft { corners.insert(.topLeft) }
        if topRight { corners.insert(.topRight) }
        if bottomRight { corners.insert(.bottomRight) }
        if bottomLeft { corners.insert(.bottomLeft) }

        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))

        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = path.cgPath
        self.layer.mask = maskLayer

        self.backgroundColor?.setFill()
        path.fill()
        borderColor.setStroke()
        path.stroke()
        let textToDraw = self.attributedText!
        textToDraw.draw(in: rect)
    }
}

I set textcolor of label in IB to white, but after set the label to this class, the color of text become black!