Swift中2个初始化器的奇怪问题

时间:2018-04-27 10:54:57

标签: ios swift initialization

我想为自定义按钮类创建2个初始值设定项,如下所示:

protocol CustomButtonProtocol {
    var title: String { get set }
    var cornerRadius: CGFloat { get set }
    var backgroundColor: UIColor { get set }
}

struct Button: CustomButtonProtocol {
    var title: String
    var cornerRadius: CGFloat
    var backgroundColor: UIColor
}

class CustomButton: UIButton {
var title: String? {
    didSet {
        self.setTitle(title, for: .normal)
    }
}

var cornerRadius: CGFloat = 0.0 {
    didSet {
        self.layer.cornerRadius = cornerRadius
    }
}

var color: UIColor? {
    didSet {
        self.backgroundColor = color
    }
}

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

init(with frame: CGRect, button: Button) {
    super.init(frame: frame)

    self.title = button.title
    self.cornerRadius = button.cornerRadius
    self.backgroundColor = button.backgroundColor
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

我想要有2个初始值设定项,第一个是简单初始值,第二个是传入我的Button,但问题是它只更改背景颜色但不title和{ {1}}属性,我找不到它为什么会发生。也许我没有看到什么,你能帮我找到这个bug吗?

2 个答案:

答案 0 :(得分:1)

考虑在willSet / didSet方法

中不调用属性观察者init

来自documentation

  

当您为存储属性指定默认值或在初始化程序中设置其初始值时,将直接设置该属性的值,而不调用任何属性观察者。

解决方案是在init方法中调用观察者中的代码

init(with frame: CGRect, button: Button) {
    super.init(frame: frame)

    self.title = button.title
    self.setTitle(self.title, for: .normal)
    self.cornerRadius = button.cornerRadius
    self.layer.cornerRadius = self.cornerRadius
    self.color = button.backgroundColor
    self.backgroundColor = self.color
}

如果color始终表示背景颜色,则该属性实际上是多余的。

答案 1 :(得分:1)

您已使用didSet将值更新为按钮属性。

didSet内设置值时,不会致电init

背景颜色设置正在设置,因为您错误地设置了backgroundColor代替color

self.backgroundColor = button.backgroundColor

你应该在init内/外使用/调用一次。

self.setTitle(title, for: .normal)
self.layer.cornerRadius = cornerRadius
self.backgroundColor = color