Skip to content

NSLayoutConstraint

Ken Harris edited this page Sep 14, 2020 · 4 revisions

Be sure to clear the .translatesAutoresizingMaskIntoConstraints flag on your views, when you add layout constraints.

The documentation says you can override layout(), but I've never gotten this to work. If you're tempted, just add fixed constraints with static positions. It's silly but it works reliably.

Be sure to call super.updateConstraints() in your override.

Performance

A view often has some permanent constraints, and some temporary ones. Put as much as you can in the permanent set -- do these once. Then in updateConstraints(), only replace the ones that changed. If the constraints never change, you can install them once in that method, and set a flag to indicate "don't bother updating anything".

For setting constraints, the visual format language seems nice, but it's the slowest. If you're updating constraints much, be aware that parsing the ASCII art takes time. I've seen significant speedups simply by replacing these with anchors, in places where constraints are updated frequently.

Debugging

To show constraint violations in development, I do this in my applicationWillFinishLaunching() (and be sure to set "DEBUG", in Debug mode):

#if DEBUG
    UserDefaults.standard.set(true, forKey: "NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints")
#endif

It usually works, but not always. (My Retina MacBook is much more likely to display it than my non-Retina Mac Pro, perhaps because it's on 10.12 rather than 10.11.) Don't bother clicking the "Exercise Ambiguity" button -- I've never seen that do anything at all.

Baseline

"Baseline" alignment is super handy, but be aware that the baseline of an empty string is funny. If you've got, for example, an NSPopUpButton where one of the choices is empty, when the user selects that, any text aligned to the popup's baseline will jump. Easy workaround: put a non-breaking space in the popup. It's really hard to put a nbsp (option-space) in IB -- the easiest way is probably to type it in a Safari URL bar, copy it, and then use the right-click menu to paste it in IB.

Clone this wiki locally