Auto-layout XIB embedded in programmatic UIView not sizing to parent

15,206

The reason it doesn't resize itself to fill its new superview is that you haven't arranged for it to do that. In short, you need to add constraints, in code, to relate the two views after adding one to the other.

Most likely, IB set the view to translate its autoresizing mask to constraints. What its autoresizing mask is can be hard to determine from the NIB when it's set to use auto layout.

Anyway, when you add it to the superview, the automatically generated constraints maintain its current frame. When the superview resizes, they resize it according to the autoresizing mask (probably allowing width and height to vary but not the distance to the superview edges).

When you're using auto layout, you should do the following:

  • Either turn off translatesAutoresizingMaskIntoConstraints in the NIB or turn it off in the code which adds it to the superview. Which of those approaches you take depends on whether you anticipate that the view will ever be added as a subview of a framework view class that manages the layout of its subviews. If you might, then you should leave it on in the NIB and let that class decide whether to turn it off.

  • After adding the view to its superview, add constraints to the superview which controls where the view should be laid out.

Share:
15,206
devios1
Author by

devios1

I am a coder: an architect of thought. My name is Logan. I am the founder and sole employee of The Little Software Company. My current project is developing a textual layout language to replace Auto Layout and Interface Builder (ambitious huh?). I'm currently working for Quetzal POS on our next-gen iPad based point of sale.

Updated on June 08, 2022

Comments

  • devios1
    devios1 almost 2 years

    I have a xib file representing a simple view with auto-layout that I am instantiating with [[NSBundle mainBundle] loadNibNamed:@"name"][0] and adding to a programmatically-created UIView via addSubview:.

    The problem is that the view is not stretching to meet the size of the view it is embedded in; rather it appears to be defaulting to the size that was specified in the xib file. (I also can't find any way to set constraints on the container view itself in the xib file, only its subviews.)

    Also somewhat strangely, when I rotate the iPad, the view's width further shrinks proportionately. So it's clearly wired up somehow, but with the wrong initial values.

    What connection am I missing to get this embedded view to fit the view hierarchy properly?

    Screenshots (magenta colouring added for debugging):

    screenshot 1

    After rotating to portrait:

    screenshot 2

  • devios1
    devios1 over 9 years
    Thanks for the help. It's too bad Xcode doesn't allow constraints to be set up for this in interface builder. Normally I like doing things in code, but auto-layout is definitely not one of those things. ;) I ended up installing the PureLayout library (github.com/smileyborg/PureLayout) and its autoPinEdgesToSuperviewEdgesWithInsets method is working great. Cheers!
  • Ken Thomases
    Ken Thomases over 9 years
    You're welcome. Constraints relate two views. In a view NIB, the superview isn't present, so there's nothing for the constraints to relate to. Furthermore, the constraints would have to be added to the superview, not to the view in the NIB. Lastly, one important use case for a view NIB is for views which may be used in various contexts. It is not appropriate for the view to dictate how it will relate to its environs in arbitrary contexts. That's a job for the controller which loads it and adds it into a another view hierarchy.
  • Troy Sartain
    Troy Sartain over 6 years
    I don't know if 3 years has changed this, but when you said "In a view NIB, the superview isn't present", I thought: but in a storyboard where a view of that class has been placed in a scene, there should be enough information there to determine that superview. IMHO, IB should just handle that. Unless I'm missing something and the Xcode folks just shrug and say it's not worth our time to add that capability.