渐变层未显示在UIButton上

时间:2019-02-16 13:23:32

标签: swift uibutton swift4 cagradientlayer

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

    }

}

2 个答案:

答案 0 :(得分:0)

替换

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

使用

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

添加总是很好的

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

答案 1 :(得分:0)

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

  1. 而不是将渐变添加为子层,而是使其成为UIButton的{​​{3}}。这样可以使动画效果更好(例如,如果按钮在设备旋转时更改大小)。

    执行此操作时,请删除所有尝试设置frame中的gradientLayer的尝试。

  2. layoutSubviews中,您将不再需要更新gradientLayer.frame,因此将其完全删除,但是您确实想在此处进行四舍五入。

  3. 这几乎无关紧要,但是设置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
    }
}