Градиентный слой не отображается на UIButton - PullRequest
0 голосов
/ 16 февраля 2019

Я пытаюсь создать пользовательскую кнопку UIB, которую я могу использовать в своем приложении.Я хотел бы применить градиент в качестве фона, но этот градиент не отображается с помощью этого очень простого кода.Было бы очень полезно, если бы кто-то мог указать на мою ошибку в коде ниже.

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 голосов
/ 16 февраля 2019

Sh_Khan прав насчет CGColor ссылок, но есть несколько дополнительных уточнений:

  1. Вместо того, чтобы добавлять градиент в качестве подслоя, сделайте его layerClass из UIButton.Это делает анимацию намного лучше (например, если кнопка меняет размер при вращении устройства).

    Когда вы сделаете это, удалите все попытки установить 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
    }
}
0 голосов
/ 16 февраля 2019

Заменить

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

на

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

И всегда хорошо добавить

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