首页 > 解决方案 > 如何在 Swift 4 中初始化代码生成的按钮边框

问题描述

我使用代码来创建按钮边框。

出于某种原因,我必须更改按钮边框的形状。

但是,mask生成的边框不是用下面的代码初始化的。

button.backgroundColor = .clear
button.layer.CornerRadius = 0

在 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
}

在 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)
}

第二次绘制边框(运行SecChange()),它与第一个边框重叠。

请帮我初始化我画的第一个边框。

(运行SecChange()和运行FirstChange()初始化边框成功。)

标签: iosswiftuibuttonbordercalayer

解决方案


因为您要添加一个CAShapeLayer,所以UIButton您需要从按钮中删除该层。为此,您可以给图层 aname并添加一个新方法来删除图层并在您的第二次更改中调用该新方法。此外,您应该在再次调用时移除边框层round(corners:radius:borderColor:borderWidth:),否则您最终会在顶部添加另一层。

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()
        }
    }
}

最好的,卡斯滕


推荐阅读