渐变层未显示在 UIButton 上

Posted

技术标签:

【中文标题】渐变层未显示在 UIButton 上【英文标题】:Gradient Layer not showing on UIButton 【发布时间】:2019-02-16 13:23:32 【问题描述】:

我正在尝试创建一个可以在整个应用程序中使用的自定义 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)

    


【问题讨论】:

【参考方案1】:

替换

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

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

添加总是好的

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

【讨论】:

【参考方案2】:

Sh_Khan 对 CGColor 的引用是正确的,但还有一些改进:

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

    执行此操作时,请删除所有尝试设置framegradientLayer

    layoutSubviews 中,您将不再需要更新gradientLayer.frame,因此将其完全删除,但您确实希望将圆角放在那里。

    这几乎没有关系,但是当您设置layer.cornerRadius(或视图、其层或该层的子层的任何属性)时,您永远不应该引用self.frame。视图的frame 是父视图坐标系中的CGRect。只在子类中引用视图的bounds;绝不是frame

因此:

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
    

【讨论】:

以上是关于渐变层未显示在 UIButton 上的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 的渐变未显示

如何创建具有渐变和突出显示的 UIButton?

针对不同状态更改 UIButton 的渐变

地理服务器中的图层未显示在 OpenLayers 中

蓝色渐变图像被错误地拉​​伸为 UIButton 的橙色渐变图像

Google 地图 - KML 图层未出现在地图上