How do you make Interface Builder respect a custom view's intrinsic content size in constraint based layout?

Set a placeholder intrinsic content size — a "guess," if you will — in Interface Builder.

  1. Select your custom view.
  2. Show the size inspector (Shift5).
  3. Change the "Intrinsic Size" drop-down from "Default (System Defined)" to "Placeholder."
  4. Enter reasonable guesses at your view's runtime width and height.

These constraints are removed at compile-time, meaning they will have no effect on your running app, and the layout engine will add constraints as appropriate at runtime to respect your view's intrinsicContentSize.


How to actually do this, 2019

import UIKit

@IBDesignable class TagPerson: ShadowRoundedImageView {

    override var intrinsicContentSize: CGSize {
        var s = super.intrinsicContentSize
        s.height = 40
        s.width = 40
        return s
    }

    override func prepareForInterfaceBuilder() {
        invalidateIntrinsicContentSize()
    }

}

However, there is a problem. Xcode is buggy. You can sometimes reset it by:

The above will of course work flawlessly at runtime. But it randomly fails to work in interface builder (even with 11+).

To make it cycle, try

  1. The usual 'Refresh all views'

  2. Attach and delete a pointless constraint to one of your intrinsic size views. (I've noticed if you have a number of them, doing this to one is usually enough to make Xcode cycle, then they all work.)

  3. And finally:

Xcode has an "intrinsic size placeholder" feature.

enter image description here

Select one or more of your intrinsic-size elements. Toggle the bizarre placeholder thing back and fore a few times. Often that makes it cycle and the view will then work correctly.

At worst, restarting Xcode with the usual clean-everything will, sometimes, get it working.