如何将渐变边框颜色应用于UIButton?

时间:2019-11-02 04:12:39

标签: ios uibutton gradient

我想实现这样的目标。我已经搜索了。我得到一些建议,可以将渐变视图放置在按钮后面,高度和宽度要比按钮大。但是我想要精确的拐角半径和带有渐变的边框颜色。

sample image

2 个答案:

答案 0 :(得分:2)

您可以创建自己的BorderedButton子类,该子类将:

  • 添加渐变子层;
  • 创建由边界路径组成的形状图层;还有
  • 使用该形状层作为渐变层的蒙版,以生成路径形状的渐变边界。

例如:

@IBDesignable
class BorderedButton: UIButton {
    @IBInspectable var lineWidth:    CGFloat = 3  { didSet { setNeedsLayout() } }
    @IBInspectable var cornerRadius: CGFloat = 10 { didSet { setNeedsLayout() } }

    let borderLayer: CAGradientLayer = {
        let borderLayer = CAGradientLayer()
        borderLayer.type = .axial
        borderLayer.colors = [#colorLiteral(red: 0.6135130525, green: 0.3031745553, blue: 0.9506058097, alpha: 1).cgColor, #colorLiteral(red: 0.9306473136, green: 0.1160953864, blue: 0.8244602084, alpha: 1).cgColor]
        borderLayer.startPoint = CGPoint(x: 0, y: 1)
        borderLayer.endPoint = CGPoint(x: 1, y: 0)
        return borderLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configure()
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        borderLayer.frame = bounds

        let mask = CAShapeLayer()
        let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
        mask.path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
        mask.lineWidth = lineWidth
        mask.fillColor = UIColor.clear.cgColor
        mask.strokeColor = UIColor.white.cgColor
        borderLayer.mask = mask
    }
}

private extension BorderedButton {
    func configure() {
        layer.addSublayer(borderLayer)
    }
}

请注意:

  • 我更新了渐变层的frame以及mask方法中用作layoutSubviews的路径,这可以确保在尺寸改变时正确显示边框(例如,您使用约束条件来定义视图的大小。
  • 我制作了这个@IBDesignable,以便您甚至可以将其添加到情节提要中,然后您会看到它正确呈现。
  • 我已将cornerRadiuslineWidth设为@IBInspectable,以便您可以在IB中进行调整(并且因为它们有didSet个观察者来设置“需求布局” ”,他们将确保在情节提要中可以观察到更改。

反正会产生:

enter image description here

答案 1 :(得分:-1)

extension CALayer {
    func addGradienBorder(colors:[UIColor],width:CGFloat = 1) {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame =  CGRect(origin: CGPointZero, size: self.bounds.size)
        gradientLayer.startPoint = CGPointMake(0.0, 0.5)
        gradientLayer.endPoint = CGPointMake(1.0, 0.5)
        gradientLayer.colors = colors.map({$0.CGColor})

        let shapeLayer = CAShapeLayer()
        shapeLayer.lineWidth = width
        shapeLayer.path = UIBezierPath(rect: self.bounds).CGPath
        shapeLayer.fillColor = nil
        shapeLayer.strokeColor = UIColor.blackColor().CGColor
        gradientLayer.mask = shapeLayer

        self.addSublayer(gradientLayer)
    }