这段代码是我从一节在线课程中学到的,这节课教我如何绕道而行。
我注释掉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中讨论)。
但是,如果您出于某种原因以编程方式实例化按钮呢?在这种情况下,awakeFromNibprepareForInterfaceBuilder都不会被调用!
所以,我建议在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
    }
}

10-08 12:14