UIButton为什么不以渐变显示

问题描述 投票:1回答:3

嗨,我是Swift和Xcode的新手,只是学习基础知识。我已经以编程方式添加了一个渐变层,然后使用主情节提要板添加了UIButton并为其分配了出口,但是当我运行代码时,渐变层会显示但按钮会显示,但是,当我删除渐变层时,显示UIButton。附件是同时使用渐变和代码时将发生的情况的屏幕截图,并会附上a。

class ViewController: UIViewController {
    let layer = CAGradientLayer()

    @IBOutlet weak var pressMeButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        layer.frame = view.bounds
        layer.colors = [UIColor.white.cgColor, UIColor(red: 128/255, green: 206/255, blue: 255/255, alpha: 1).cgColor]
        layer.startPoint = CGPoint(x: 0, y: 0)
        layer.endPoint = CGPoint(x: 0, y: 0.4)
        view.layer.addSublayer(layer)

        pressMeButton.layer.cornerRadius = 25.0
        pressMeButton.layer.borderWidth = 0.8
        pressMeButton.layer.borderColor = UIColor.black.cgColor
        pressMeButton.setTitle("Press Me", for: .normal)
        pressMeButton.setTitleColor(.black, for: .normal)
    }
}

带有情节提要的代码显示了按钮的放置,没有按钮的模拟器:

“屏幕快照”

ios swift xcode storyboard ios-simulator
3个回答
0
投票

您是在视图顶部添加图层,而您之前已经添加了UIButton。因此该层与UIButton重叠。

您需要在控制器的主视图中添加一个容器视图,然后在其上添加渐变层。


0
投票

主要问题是渐变层位于按钮顶部。第二个问题(您尚未提到)是,如果旋转设备,它将无法响应框架中的更改。

最佳解决方案是定义一个GradientView,其衬里层由其layerClass决定为layerClass。这样(a)它将始终位于按钮下方; (b)它会自动适应CAGradientLayer的更改(并且在动画过程中也比framelayoutSubviews的方法更优雅地进行调整):

viewDidLayoutSubviews

使用此@IBDesignable class GradientView: UIView { override class var layerClass: AnyClass { return CAGradientLayer.self } private var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer } @IBInspectable var startColor: UIColor = .white { didSet { updateGradient() } } @IBInspectable var endColor: UIColor = #colorLiteral(red: 0.5019607843, green: 0.8078431373, blue: 1, alpha: 1) { didSet { updateGradient() } } @IBInspectable var startPoint: CGFloat = 0 { didSet { updateGradient() } } @IBInspectable var endPoint: CGFloat = 0.4 { didSet { updateGradient() } } override init(frame: CGRect = .zero) { super.init(frame: frame) updateGradient() } required init?(coder: NSCoder) { super.init(coder: coder) updateGradient() } } private extension GradientView { func updateGradient() { gradientLayer.colors = [startColor, endColor].map { $0.cgColor } gradientLayer.startPoint = CGPoint(x: 0, y: startPoint) gradientLayer.endPoint = CGPoint(x: 0, y: endPoint) } } 类,然后可以将视图控制器视图的基类设置为@IBDesignable,它将在按钮下方呈现该基类,并在Interface Builder中正确显示。例如,单击背景视图,然后转到最右侧面板中的“身份检查器”选项卡,然后在“自定义类别”部分中设置“类别”:

GradientView

如果需要,您可以在IB中直接更改开始/结束颜色和开始/结束点,方法是选择右侧的“属性检查器”面板:

enter image description here

很显然,如果您采用这种方式,则完全不需要在enter image description here中浏览视图的图层。但是,如果要以编程方式更改它,可以执行以下操作:

viewDidLoad

但是我亲自在IB中设置颜色(或其他颜色)。然后,我将所有“视图配置”代码保留在其所属的override func viewDidLoad() { super.viewDidLoad() if let view = view as? GradientView { view.startColor = .black view.endColor = .red } } 类中,而不是在视图控制器中。


0
投票

感谢所有帮助,但最终我创建了一个带有用于进行渐变的参数的玻璃,以及另一个带有用于某些颜色的参数的玻璃,然后能够将它们拉入viewLoad。

© www.soinside.com 2019 - 2024. All rights reserved.