Reputation: 121
I am trying to round three corners of label and button by following this: rounded button
But the result is:
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
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