Swift 渐变层未显示在UIButton上

Swift 渐变层未显示在UIButton上,swift,uibutton,swift4,cagradientlayer,Swift,Uibutton,Swift4,Cagradientlayer,我正在尝试创建一个自定义UIButton,我可以在整个应用程序中使用它。我想应用一个梯度作为它的背景,但梯度并没有显示使用这个非常简单的代码。 如果有人能指出我在下面代码中的错误,那将非常有帮助 class GradientBtn: UIButton { let gradientLayer = CAGradientLayer() override init(frame: CGRect) { super.init(frame: frame) t

我正在尝试创建一个自定义UIButton,我可以在整个应用程序中使用它。我想应用一个梯度作为它的背景,但梯度并没有显示使用这个非常简单的代码。 如果有人能指出我在下面代码中的错误,那将非常有帮助

class GradientBtn: UIButton {

    let gradientLayer = CAGradientLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)

        themeConfig()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        themeConfig()
    }

    private func themeConfig() {
        //shadow
        layer.shadowOffset = CGSize.zero
        layer.shadowColor = UIColor.gray.cgColor
        layer.shadowOpacity = 1.0

        //titletext
        setTitleColor(Theme.colorWhite, for: .normal)
        titleLabel?.font = UIFont(name: Theme.fontAvenir, size: 18)

        //rounded corners
        layer.cornerRadius = frame.size.height / 2

        //gradient
        gradientLayer.locations = [0.0, 1.0]
        gradientLayer.colors = [Theme.colorlightBlue, Theme.colorMidBlue]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
        gradientLayer.frame = bounds
        layer.insertSublayer(gradientLayer, at: 0)

    }

}
替换

gradientLayer.colors = [Theme.colorlightBlue, Theme.colorMidBlue]


加上它总是好的

override func layoutSubviews() {
    super.layoutSubviews()
    gradientLayer.frame = self.bounds
}

关于
CGColor
references,Sh_Khan是正确的,但还有一些额外的改进:

  • 与其将渐变添加为子层,不如将其设置为
    ui按钮的子层。这使得动画效果更好(例如,如果按钮在设备旋转时改变大小)

    执行此操作时,请删除设置
    渐变层
    的所有尝试

  • layoutSubviews
    中,您将不再需要更新
    gradientLayer.frame
    ,因此请将其完全删除,但您确实希望在此处设置圆角

  • 这不太可能有什么关系,但是当您设置
    layer.cornerRadius
    (或视图的任何属性、其层或该层的子层)时,您永远不应该参考
    self.frame
    。视图的
    是superview坐标系中的
    CGRect
    。仅在子类中引用视图的
    边界
    ;永远不要使用它的

  • 因此:

    override func layoutSubviews() {
        super.layoutSubviews()
        gradientLayer.frame = self.bounds
    }
    
    class GradientBtn: UIButton {
        
        override class var layerClass: AnyClass { return CAGradientLayer.self }
        private var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer }
        
        override init(frame: CGRect = .zero) {
            super.init(frame: frame)
            
            themeConfig()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            
            themeConfig()
        }
        
        private func themeConfig() {
            //shadow
            layer.shadowOffset = .zero
            layer.shadowColor = UIColor.gray.cgColor
            layer.shadowOpacity = 1
            
            //titletext
            setTitleColor(Theme.colorWhite, for: .normal)
            titleLabel?.font = UIFont(name: Theme.fontAvenir, size: 18)
            
            //gradient
            gradientLayer.locations = [0, 1]
            gradientLayer.colors = [Theme.colorlightBlue, Theme.colorMidBlue].map { $0.cgColor }
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 1, y: 1)
        }
        
        override func layoutSubviews() {
            super.layoutSubviews()
            
            layer.cornerRadius = min(bounds.height, bounds.width) / 2
        }
    }