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

Posted

技术标签:

【中文标题】如何将渐变边框颜色应用于 UIButton?【英文标题】:How to apply gradient border color to UIButton? 【发布时间】:2019-11-02 04:12:39 【问题描述】:

我想实现这样的目标。我已经搜索过了。我收到建议,我可以在按钮后面放置一个渐变视图,其高度和宽度大于按钮。但我想要精确的圆角半径和渐变边框颜色。

【问题讨论】:

你看过这个答案吗? ***.com/a/36836787 【参考方案1】:

您可以创建自己的 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 和在layoutSubviews 方法中用作mask 的路径,以确保在大小变化时正确呈现边框(例如,您正在使用约束定义视图的大小)。 我制作了这个@IBDesignable,这样您甚至可以将它添加到情节提要中,并且您会看到它正确呈现。 我已将cornerRadiuslineWidth 设为@IBInspectable,以便您可以在IB 中调整它们(并且因为他们有didSet 观察者设置“需要布局”,他们将确保更改可在情节提要中观察到)。

无论如何,这会产生:

【讨论】:

【参考方案2】:
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)
    

【讨论】:

以上是关于如何将渐变边框颜色应用于 UIButton?的主要内容,如果未能解决你的问题,请参考以下文章

两个 UIButton 形成一个具有渐变颜色,另一个具有边框和圆角

自定义 UIButton 类 - 渐变离开按钮边框

渐变作为按钮边框颜色?

UIButton 边框中的生涩渐变

使 UIView 渐变的边框颜色

圆角渐变 UIButton iOS