[英]Why Is My IBDesignable UIButton Subclass Not Rendering In Interface Builder?
In the screen shot below please note that the DropDownButton (the selected view) is not being live rendered. 在下面的屏幕截图中,请注意,没有实时渲染DropDownButton(选定的视图)。 Also, please note the "Designables Up To Date" in the Identity Inspector. 另外,请注意身份检查器中的“最新的Designables”。 Finally, please note the two break points in the assistant editor: if I execute Editor -> Debug Selected Views then both of these break points are hit. 最后,请注意助手编辑器中的两个断点:如果执行“编辑器”->“调试选定的视图”,则两个断点都将被击中。
Here's what It looks like when I run it: 这是我运行它时的样子:
Here's the code: 这是代码:
@IBDesignable
class DropDownButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
private func initialize() {
if image(for: .normal) == nil {
//setImage(#imageLiteral(resourceName: "DropDown"), for: .normal)
let bundle = Bundle(for: DropDownButton.self)
if let image = UIImage(named: "DropDown", in: bundle, compatibleWith: nil) {
setImage(image, for: .normal) // Editor -> Debug Selected Views reaches this statement
}
}
if title(for: .normal) == nil {
setTitle("DropDown", for: .normal) // Editor -> Debug Selected Views reaches this statement
}
addTarget(self, action: #selector(toggle), for: .touchUpInside)
}
override func layoutSubviews() {
super.layoutSubviews()
if var imageFrame = imageView?.frame, var labelFrame = titleLabel?.frame {
labelFrame.origin.x = contentEdgeInsets.left
imageFrame.origin.x = labelFrame.origin.x + labelFrame.width + 2
imageView?.frame = imageFrame
titleLabel?.frame = labelFrame
}
}
override func setTitle(_ title: String?, for state: UIControlState) {
super.setTitle(title, for: state)
sizeToFit()
}
public var collapsed: Bool {
return imageView?.transform == CGAffineTransform.identity
}
public var expanded: Bool {
return !collapsed
}
private func collapse() {
imageView?.transform = CGAffineTransform.identity
}
private func expand() {
imageView?.transform = CGAffineTransform(rotationAngle: .pi)
}
@objc private func toggle(_: UIButton) {
if collapsed { expand() } else { collapse() }
}
}
First Edit: 第一次编辑:
I added the prepareForInterfaceBuilder method as per @DonMag's answer. 我按照@DonMag的答案添加了prepareForInterfaceBuilder方法。 Doing so made an improvement but there is still something wrong: Interface builder seems confused about the frame. 这样做进行了改进,但是仍然存在问题:接口构建器似乎对框架感到困惑。 When I select the button only the title is selected, not the image (ie triangle). 当我选择按钮时,仅标题被选中,而不是图像(即三角形)。 I added a border; 我加了一个边框; it goes around both the title and the image. 它围绕标题和图像。 Here is a picture: 这是一张图片:
If I drag the button to a new position then everything moves, title and image. 如果将按钮拖动到新位置,则所有内容,标题和图像都会移动。
Also, it surprised me that prepareForInterfaceBuilder made a difference. 此外,prepareForInterfaceBuilder有所作为也令我感到惊讶。 My understanding of this method it that it allows me to do interface builder only setup such as providing dummy data. 我对这种方法的理解是,它允许我仅进行接口构建器设置,例如提供虚拟数据。
Add this: 添加:
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
initialize()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.