我正在快速构建一个新的iOS应用,并尝试制作一个自定义IBDesignable UIButton类以在设计器中使用。 我的代码似乎在运行时在构建器或应用程序本身中均无效。 我提供给IBInspectable变量的默认值不适用于它们。
@IBDesignable class MyButton: UIButton {
@IBInspectable var backColor: UIColor = UIColor.red {
didSet {
self.backgroundColor = backColor
}
}
@IBInspectable var textColor: UIColor = UIColor.white {
didSet {
self.setTitleColor(textColor, for: .normal)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
private func setup() {
titleLabel?.font = UIFont.systemFont(ofSize: 17)
contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
layer.cornerRadius = (frame.height / 2)
setTitle(title(for: .normal)?.uppercased(), for: .normal)
}
}
我希望在设计器/应用程序中看到带有红色背景和白色文本的按钮,但这些都不会发生。 我正在使用Swift 4.2和Xcode 10.1。
答案 0 :(得分:0)
添加这两个func
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
self.setup()
}
无需初始化
答案 1 :(得分:0)
设置属性默认值不会调用didSet
子句。
您需要类似:
private func setup() {
titleLabel?.font = UIFont.systemFont(ofSize: 17)
contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
layer.cornerRadius = (frame.height / 2)
setTitle(title(for: .normal)?.uppercased(), for: .normal)
// I would do it differently, but this is just for demo purposes
// Also, can't assign a prop to itself, so using a temp
var tmp = self.backColor
self.backColor = tmp
tmp = self.textColor
self.textColor = tmp
}
另外,在Swift或目标C语言中,Xcode不能与IBDesignable一起使用。
确保已选中菜单项:编辑器->自动刷新视图。
您还可以显式执行编辑器->刷新所有视图。
根据我的经验-这会在一段时间后停止工作,您需要退出Xcode并重新启动它才能使其再次运行。
答案 2 :(得分:0)
确保在Interface Builder中将按钮设置为键入.custom
。
这并不明显,但默认按钮类型为.system
,无法自定义。我看到人们对此没有任何问题,但是在我的应用程序中,这始终是一个问题。
另一个问题是,如果将可检查的值保留为空,则不会调用didSet
,也不会应用默认值。
@IBInspectable var backColor: UIColor? = UIColor.red {
didSet {
updateBackground()
}
}
private func updateBackground() {
self.backgroundColor = backColor
}
func setup() {
...
updateBackground()
}