如何在Swift中向UIButton添加渐变?

问题描述 投票:0回答:2

我已经阅读了其他人的问题和答案,但没有找到对我有效的答案。

我正在使用此代码使用该图层在UIButton中添加渐变:

let gradient = CAGradientLayer()
gradient.colors = [UIColor.black.cgColor, UIColor.gray.cgColor]
gradient.locations = [0.0, 1.0]
myButton.setNeedsLayout() //I added this line then change next line to frame
gradient.frame = myButton.frame //I tried bounds
myButton.layer.insertSublayer(gradient, at: 0)

按钮有时会显示渐变,而框架按钮会显示渐变。如果我将相同的代码应用于UITabbar而不是按钮,则会出现类似的问题,则渐变不会应用于所有帧...可能是什么问题呢?解决方法?

Y无法通过应用程序的体系结构从layoutSubviews加载渐变。

swift layout uibutton gradient frame
2个回答
0
投票

要解决您的问题,通常可以更改代码的以下行,

gradient.frame = myButton.frame

gradient.frame = myButton.bounds


面临问题的原因是,当您使用视图/按钮的.frame属性时,它提供了视图/按钮相对于其超级视图的原点,可以是任何东西。

当使用.bounds属性时,原点基于其自己的视图空间,该视图空间在大多数情况下会以(0,0)点作为原点。但并非总是如此,这使我达成了以下共识,


使用自动布局时,该解决方案可能仍然会遇到问题,因为布局引擎可以在应用渐变后更改按钮的大小。

优雅的解决方案是有一个自定义按钮类,该类将应用于所有对其应用了渐变的按钮。当视图更新布局时,此类应调整渐变的大小。

class GradientButton: UIButton {
    override func layoutSubviews() {
        super.layoutSubviews()
        updateGradientLayers()
    }

    private func updateGradientLayers() {
        guard let sublayers = layer.sublayers else { return }
        for layer in sublayers {
            if let gradientView = layer as? CAGradientLayer {
                gradientView.frame = bounds
            }
        }
    }
}

0
投票

我正在使用此自定义按钮样式来设置渐变。

import UIKit

class CustomButton: UIButton {

    init() {
        super.init(frame: .zero)
        customInit()
    }

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

    private func customInit() {
        setupGradient()
    }

    private func setupGradient() {
        let gradient = CAGradientLayer()
        gradient.name = "gradient"
        gradient.frame = self.bounds
        gradient.cornerRadius = self.layer.cornerRadius

        gradient.colors = [
            UIColor(red: 1.00, green: 0.41, blue: 0.35, alpha: 1.0).cgColor,
            UIColor(red: 1.00, green: 0.00, blue: 0.67, alpha: 1.0).cgColor
        ]

        gradient.locations = [0, 1]
        gradient.startPoint = CGPoint(x: 0, y: 0)
        gradient.endPoint = CGPoint(x: 1, y: 1)

        self.layer.insertSublayer(gradient, at: 0) // insert to the back
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.