在 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 属性 在 viewWillAppear 时没有初始化。
所以有人知道我该怎么办?这会有所帮助。提前谢谢你。
将 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
函数。
我有一个带有阴影效果的自定义按钮,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 属性 在 viewWillAppear 时没有初始化。 所以有人知道我该怎么办?这会有所帮助。提前谢谢你。
将 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
函数。