Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add top level constraints and disable translatesAutoresizingMaskIntoConstraints in Interface Builder .xib file

When loading a UIView from a nib file, the view usually has translatesAutoresizingMastIntoConstraints set to YES.

As a consequence, you cannot add top level constraints to the view (e.g. width and height).

In the past I have been able to generate a top level view which does allow me to create top level constraints, and sets translatesAutoresizingMastIntoConstraints to NO.

How can I get this behavior when loading a UIView from a nib without subclassing it?

like image 566
Senseful Avatar asked Jan 10 '23 19:01

Senseful


1 Answers

Update: Although you can create constrainable views, I wouldn't recommend it because it's extremely hard to tell the difference between the two. If you ever need to modify or recreate the view, you may forget that it was a constrainable view and accidentally recreate a static view. Therefore, I would recommend that you leave top level views as static views, and manually update them after creating them from a nib:

let view = UINib(nibName: "ABCView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
view.translatesAutoresizingMaskIntoConstraints = false

If the view needs an intrinsic content size, either override intrinsicContentSize, or define its width and/or height via the nib file, by simply add a "sizing" subview that is pinned to the top level view's (i.e. the static view's) top, bottom, trailing, and leading constraints, and has a width and/or height constraint.


This seems to be an undocumented Xcode feature (tested on Xcode 6, and Xcode 7.1).

I will use the following terms:

  • Static view: the default views which do not allow top level constraints, and have translatesAutoresizingMaskIntoConstraints set to YES.
  • Constrainable view: a view which allows you to create top level constraints, and has translatesAutoresizingMaskIntoConstraints set to NO.

First let's take a look at some of their differences...

Static view

.xib contents:

<view contentMode="scaleToFill" id="bU6-qJ-x7d" userLabel="STATIC">
    <rect key="frame" x="0.0" y="0.0" width="320" height="439"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
    <nil key="simulatedStatusBarMetrics"/>
    <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
    <point key="canvasLocation" x="687" y="37.5"/>
</view>

More info:

  • <UIView: 0x7fec19ccb1b0; frame = (0 0; 320 439); autoresize = W+H; layer = <CALayer: 0x7fec19ccae80>>
  • translatesAutoresizingMaskIntoConstraints: YES
  • Cannot add top level constraints in Interface Builder.

Constrainable view

.xib contents:

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0G6-nE-8IZ" userLabel="CONSTRAINABLE">
    <rect key="frame" x="0.0" y="0.0" width="320" height="439"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <nil key="simulatedStatusBarMetrics"/>
    <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
    <point key="canvasLocation" x="687" y="-455.5"/>
</view>

More info:

  • <UIView: 0x7f9503eb2ba0; frame = (0 0; 320 439); autoresize = RM+BM; layer = <CALayer: 0x7f9503e9dc80>>
  • translatesAutoresizingMaskIntoConstraints: NO
  • Can add top level constraints in Interface Builder.

Subtle differences:

  • The static one has an <autoresizingMask ... element.
  • Dragging in a UIView from the Object Library into the whitespace produces a Static view.
  • Dragging in a UIView from the Object Library as a subview of another view produces a Constrainable view (even if you don't define any constraints).

How to create a new constrainable view:

  1. Drag a UIView into another to create a subview. (If you don't have anything in a nib, you need to temporarily drag a view in there, and delete it at the end of this process).
  2. Add a constraint to that view which the view will own (e.g. create a width constraint).
  3. Drag the view out of its superview and drop it on the white part of the Interface Builder document.
  4. It should now not have a superview and you should be able to create top level constraints on the view.

How to convert an existing static view to a constrainable view:

  1. Drag the view from the Document Outline into another view so that it becomes a subview (again, you may need to create a temporary view for this.)
  2. Add at least one top level constraint (e.g. create a height constraint).
  3. Drag the view back to the whitespace.
  4. Change the view's size back to Freeform in the Attributes Inspector under Simulated Metrics.

How to convert an existing constrainable view back to a static view:

  1. Drag the view from the Document Outline into another view so that it becomes a subview (again, you may need to create a temporary view for this.)
  2. Delete all its top level constraints (e.g. delete its width/height constraints).
  3. Drag the view back to the whitespace.
  4. Change the view's size back to Freeform in the Attributes Inspector under Simulated Metrics.
like image 178
Senseful Avatar answered Jan 21 '23 03:01

Senseful