I'm no great fan of @IBDesignable
, but in playing around with it I find that if you add a subview in prepareForInterfaceBuilder
, the subview is added but constraints that you apply to it are not obeyed.
Is this a known limitation of prepareForInterfaceBuilder
? That would make sense; I imagine that this method should be confined to doing things like giving a label some dummy text.
Make sure when adding a subview in prepareForInterfaceBuilder
that you set its translatesAutoresizingMaskIntoConstraints
property to false
if you want to use constraints on it and have it show up properly in Interface Builder. Such as:
@IBDesignable class View: UIView {
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
let subview = UIView()
// Make sure to set this to false!
subview.translatesAutoresizingMaskIntoConstraints = false
// Just setting the background color so it can be seen in IB.
subview.backgroundColor = .blue
// Must add it as a subview before activating any constraints.
addSubview(subview)
// Adding some example constraints with some padding to make sure they're behaving properly.
NSLayoutConstraint.activate(
[subview.topAnchor.constraint(equalTo: topAnchor, constant: 20),
subview.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
subview.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20),
subview.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20)]
)
}
}
This is an easy mistake to make because Xcode (10.3 as of writing this answer) does not give you any feedback about what's happening with the layout engine during IBDesignable
rendering (no console log messages, no errors in Interface Builder, and nothing in the Report Navigator).