Share Knowledge
Share Knowledge

Reputation: 121

Corner are not round of UILabel and UIbutton ios swift

I am trying to round three corners of label and button by following this: rounded button

But the result is:

Image of issue

some corners of labels are rounding and some are not.Similarly its happening with button and width is exceeding and button going out of tableview.

this is the code of extension i am using:

extension UIButton{
    func roundedButton(){
        let maskPAth1 = UIBezierPath(roundedRect: self.bounds,
                                     byRoundingCorners: [.topLeft, .bottomLeft, .bottomRight],
                                     cornerRadii:CGSize(width:8,height:8))
        let maskLayer1 = CAShapeLayer()
        maskLayer1.frame = self.bounds
        maskLayer1.masksToBounds=true
        maskLayer1.path = maskPAth1.cgPath
        self.layer.mask = maskLayer1

    }
}

extension UILabel{
    func roundedLabel(){
        let maskPAth1 = UIBezierPath(roundedRect: self.bounds,
                                     byRoundingCorners: [.topRight,.bottomRight,.bottomLeft],
                                     cornerRadii:CGSize(width:10,height:10))
        let maskLayer1 = CAShapeLayer()
        maskLayer1.frame = self.bounds
        maskLayer1.cornerRadius=5
         maskLayer1.masksToBounds=true
        maskLayer1.path = maskPAth1.cgPath
        self.layer.mask = maskLayer1

    }
}

I am calling these function in

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}

Upvotes: 0

Views: 815

Answers (1)

Lësha Turkowski
Lësha Turkowski

Reputation: 1391

That happens because bounds of these labels and buttons are most probably different when you call rounded...() methods and when they are presented in a table view.

That's because the bounds value that you use to create the UIBezierPath is different from one that these views have after they are presented in the cell. Table view layouts a cell and if the CAShapeLayer you create exceeds its bounds, it gets "cut off".

You should create a subclasses of UIButton and UILabel that would update the bezier path of their masks every time they layout.

class RoundedLabel: UILabel {

    override func layoutSubviews() {
        super.layoutSubviews()

        let maskPath = UIBezierPath(roundedRect: bounds,
                                    byRoundingCorners: [.topRight, .bottomRight, .bottomLeft],
                                    cornerRadii: CGSize(width: 10, height: 10))

        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.cornerRadius = 5
        maskLayer.masksToBounds = true
        maskLayer.path = maskPath.cgPath
        layer.mask = maskLayer
    }
}

As further optimization you could lazily initialize the mask layer (meaning it would be created when it's accessed for the first time) and only change it's frame and path in the layoutSubviews method.

class RoundedLabel: UILabel {

    private lazy var maskLayer: CAShapeLayer = {
        let maskLayer = CAShapeLayer()
        maskLayer.cornerRadius = 5
        maskLayer.masksToBounds = true
        self.layer.mask = maskLayer

        return maskLayer
    }()

    override func layoutSubviews() {
        super.layoutSubviews()

        let maskPath = UIBezierPath(roundedRect: bounds,
                                    byRoundingCorners: [.topRight, .bottomRight, .bottomLeft],
                                    cornerRadii: CGSize(width: 10, height: 10))

        maskLayer.path = maskPath.cgPath
        maskLayer.frame = bounds
    }
}

Upvotes: 2

Related Questions