【问题标题】:Load CAShapeLayer With UIButton on viewWillAppear Method在 viewWillAppear 方法上使用 UIButton 加载 CAShapeLayer
【发布时间】:2023-08-08 13:25:02
【问题描述】:

我有一个带有一些阴影效果的自定义按钮,遵循我用来创建从 * 获得的自定义按钮的类。它使用 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 类创建了 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)
    }

一切正常。现在我想要的是每当视图出现时,我希望默认选择第一个按钮,这是我在 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 方法上设置默认选定按钮时才会出现此问题,否则它可以正常工作。 我认为出现问题是因为在 viewWillAppear 时未初始化 CustomButton 的 shadowLayer 属性。 所以有人知道我该怎么办吗?这会很有帮助。提前谢谢你。

【问题讨论】:

  • 首先分配阴影颜色和所有效果,然后调用 uibutton 选择。我认为在这里您需要逐行检查执行情况。
  • 因为 viewWillAppear 首先被调用。但是您在 layoutSubViews 中分配了阴影效果。执行流程见此链接*.com/questions/5562938/…

标签: ios swift uibutton cashapelayer viewwillappear


【解决方案1】:

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函数。

【讨论】:

  • 谢谢先生的回答。它工作得很好。我是 swift 和 ios 编程的新手。
最近更新 更多