这段代码是我从一节在线课程中学到的,这节课教我如何绕道而行。
我注释掉awakeFromNib(
)和prepareForInterfaceBuilder()
方法并运行模拟器,结果是相同的:按钮仍然显示圆角而不显示awakeFromNib()
。
@IBDesignable
class RoundedButton: UIButton {
@IBInspectable var cornerRadius: CGFloat = 4.0 {
didSet {
self.layer.cornerRadius = cornerRadius
}
}
override func awakeFromNib() {
self.setUpView()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.setUpView()
}
func setUpView() {
self.layer.cornerRadius = 3.0
}
}
我想知道,当我已经在观察者中设置了拐角半径时,为什么要使用
awakeFromNib()
和prepareForInterfaceBuilder()
? 最佳答案
你问:
我想知道,当我已经在观察者中设置了拐角半径时,为什么要使用awakeFromNib()
和prepareForInterfaceBuilder()
?
问题是,如果您将按钮添加到脚本场景中,而根本没有设置@IBInspectable
属性,该怎么办。您的层的角半径永远不会设置为3
(或4
),因为只有在初始化之后更改观察者时才会调用观察者。你需要确保你没有一个执行路径,在那里观察者没有被调用(或者至少根据你的属性值更新层的角半径)。你需要通过其中一种方法来配置你的拐角半径(或者,我将在下面的init
中讨论)。
但是,如果您出于某种原因以编程方式实例化按钮呢?在这种情况下,awakeFromNib
和prepareForInterfaceBuilder
都不会被调用!
所以,我建议在init
中进行。这涵盖了所有场景:
@IBDesignable
class RoundedButton: UIButton {
@IBInspectable var cornerRadius: CGFloat = 3.0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
override init(frame: CGRect = .zero) {
super.init(frame: frame)
setUpView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpView()
}
}
private extension RoundedButton {
func setUpView() {
layer.cornerRadius = cornerRadius
}
}
我也不知道为什么在
var
声明中有一个默认值,而在setUpView
声明中有另一个默认值,所以我只需要一个来避免歧义。顺便说一下,另一种方法是使用从
layer
获取的计算属性。这避免了任何可能的混淆(例如,您在其他地方以编程方式更改layer.cornerRadius
,您真的希望这个cornerRadius
属性返回旧的存储值,而不是该层真正使用的是什么)?@IBDesignable
class RoundedButton: UIButton {
@IBInspectable var cornerRadius: CGFloat {
get { return layer.cornerRadius }
set { layer.cornerRadius = newValue }
}
override init(frame: CGRect = .zero) {
super.init(frame: frame)
setUpView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpView()
}
}
private extension RoundedButton {
func setUpView() {
cornerRadius = 4.0
}
}