I used the code to create the button border.
I have to change the shape of the button border for some reason.
However, the border generated by mask is not initialized with the following code.
button.backgroundColor = .clear
button.layer.CornerRadius = 0
In ViewController.swift :
@IBOutlet weak var btnDelete: UIButton!
func FirstChange() {
btnDelete.layer.borderWidth = 0
btnDelete.layer.cornerRadius = 0
btnDelete.layer.borderColor = UIColor(rgb: 0xFFFFFF).cgColor
// Draw the border again
btnDelete.round(corners: [.topRight, .bottomRight], radius: 50, borderColor: UIColor(rgb: 0xced4da), borderWidth: 1)
}
func SecChange() {
btnDelete.backgroundColor = .clear // not work
// Draw the border again
btnDelete.layer.borderColor = UIColor(rgb: 0xced4da).cgColor
btnDelete.layer.borderWidth = 1
btnDelete.layer.cornerRadius = 18
}
In UIView.swift :
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
let borderLayer = CAShapeLayer()
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
The second time draw the border(run SecChange()
), it overlaps with the first border.
Please help me to initialize the first border I painted.
(Running SecChange()
and running FirstChange()
initializes the border successfully.)
since you are adding a CAShapeLayer
to the UIButton
you need to remove this layer from the button. For this you could give the layer a name
and add a new method to remove the layer and call that new method in your second change. Additionally you should remove the border layer when calling round(corners:radius:borderColor:borderWidth:)
again, otherwise you would end up with another layer on top.
func SecChange() {
btnDelete.removeBorderLayer() //remove border layer if existing
// Draw the border again
btnDelete.layer.borderColor = UIColor.gray.cgColor
btnDelete.layer.borderWidth = 1
btnDelete.layer.cornerRadius = 18
}
extension UIView {
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
removeBorderLayer()
let borderLayer = CAShapeLayer()
borderLayer.name = "borderLayer"
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
func removeBorderLayer() {
if let borderLayer = layer.sublayers?.first(where: { $0.name == "borderLayer" }) {
borderLayer.removeFromSuperlayer()
}
}
}
Best, Carsten