Вы спрашиваете:
Мне интересно, почему я должен использовать 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
}
}