在 viewWillAppear 方法上使用 UIButton 加载 CAShapeLayer

Load CAShapeLayer With UIButton on viewWillAppear Method

我有一个带有阴影效果的自定义按钮,class 我正在使用它来创建一个我从 Whosebug 获得的自定义按钮。它使用 CAShapeLayer 在按钮上产生阴影效果。

import UIKit

class CustomButton: UIButton {

var shadowLayer: CAShapeLayer!
override func layoutSubviews() {
    super.layoutSubviews()

    if shadowLayer == nil {
        shadowLayer = CAShapeLayer()
        shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath

        shadowLayer.fillColor = UIColor.white.cgColor
        shadowLayer.shadowColor = UIColor.darkGray.cgColor
        shadowLayer.shadowPath = shadowLayer.path
        shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
        shadowLayer.shadowOpacity = 0.8
        shadowLayer.shadowRadius = 2

        layer.insertSublayer(shadowLayer, at: 0)
        //layer.insertSublayer(shadowLayer, below: nil) // also works
    }
}
}

以下是屏幕图像,其中我使用此 CustomButton Class 创建了 4 个按钮,效果很好。

当单击以上四个中的任何按钮时,我将其更改为跟随 属性,因此它看起来像一个活动按钮。

// to make button active
    func setSelectedButton(sender:CustomButton){
        //sender.backgroundColor = UIColor.red
        sender.shadowLayer.fillColor = UIColor(named: "headerColor")?.cgColor
        sender.setTitleColor(UIColor.white, for: .normal)
    }
// to make button inactive 
    func setUnselected(sender:CustomButton){
        //sender.backgroundColor = UIColor.init(red: 80/255, green:101/255, blue: 161/255, alpha: 1)
        sender.shadowLayer.fillColor = UIColor.white.cgColor
        sender.setTitleColor(.black, for: .normal)
    }

一切正常。现在我想要的是每当视图出现时,我希望默认选择第一个按钮,即 routineButton 来做到这一点我在 viewWillAppearMethod

中编写了以下代码
override func viewWillAppear(_ animated: Bool) {
        self.navigationItem.title = navigationTitle
        self.view.makeToastActivity(.center)
        self.routineButton.sendActions(for: .touchUpInside) //default selection of routineButton
        loadEvaluationList(userId: 8, evaluationType: "RT") {
            self.view.hideToastActivity()
        }
    }

self.routineButton.sendActions(for: .touchUpInside) 执行它时调用 setSelectedButton(sender:CustomButton) 方法,该方法在下面的行

处给出错误
 sender.shadowLayer.fillColor = UIColor(named: "headerColor")?.cgColor

表示 shadowLayer 为零。仅当我尝试在 viewWillAppear 方法上设置默认选定按钮时才会出现此问题,否则它会正常工作。 我认为问题的发生是因为 CustomButton 的 shadowLayer 属性 在 vi​​ewWillAppear 时没有初始化。 所以有人知道我该怎么办?这会有所帮助。提前谢谢你。

shadowLayer 的初始化代码移到 init 方法中,如下所示:

import UIKit

class CustomButton: UIButton {

    var shadowLayer: CAShapeLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initShadowLayer()
    }

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

    func initShadowLayer() {
        if shadowLayer == nil {
            shadowLayer = CAShapeLayer()
            shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath

            shadowLayer.fillColor = UIColor.white.cgColor
            shadowLayer.shadowColor = UIColor.darkGray.cgColor
            shadowLayer.shadowPath = shadowLayer.path
            shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
            shadowLayer.shadowOpacity = 0.8
            shadowLayer.shadowRadius = 2

            layer.insertSublayer(shadowLayer, at: 0)
        }

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        // Reset the path because bounds could have been changed
        shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
        shadowLayer.shadowPath = shadowLayer.path
    }
}

viewWillAppear 在按钮的 layoutSubviews 之前调用,shadowLayer 尚未初始化。也尽量不要调用 sendActions(for: .touchUpInside),如果你只是想配置按钮外观,而是调用 setSelectedButton 函数。