Search code examples
iosstoryboardautolayoutuinavigationitem

Autolayout: Title View that Grows to Encompass UILabel + UIButton


I'm customizing the title view of my view controller so that displays (from left to right):

  1. A UILabel that works pretty much like the default title label,
  2. A UIButton of type info, placed right after the label at a fixed distance.

I expect that, as the label grows horizontally to accommodate longer text, it pushes the button farther to the right (the horizontal space between label and button remaining constant), while the whole title view resizes itself to contain label and button, while staying centred in the navigation bar.

This is what I did (Interface Builder):

  1. Drag a UINavigationItem into the navigation bar;
  2. Drag a UIView into the navigation item, to act as title view;
  3. Drag label and button into title view, position and resize.
  4. Setup the following constraints:

    Label -> Title View:

    1. Leading Space to Container Margin
    2. Center Vertically in Container

    Button -> Title View:

    1. Trailing Space to Container Margin
    2. Center Vertically in Container

(Title view itself is unconstrained)

However, the title view remains a fixed size. If at runtime I set a title longer than the placeholder set in the storyboard, it gets trimmed ("..."):

enter image description here

If instead I set a shorter one, additional space appears between the label and button:

enter image description here

Alternatively, if I add the following constraint:

Label -> Button: 1. Horizontal Spacing

...now the button gets completely hidden by the label:

enter image description here

How can I have the title view grow horizontally (while remaining centred) just so that it fits both the (flexible) label and (fixed) button, and keeps the space between them fixed?


Solution

  • The navigation item isn't setup to deal with this directly. You need to use your constraints to set the frame of the title view and then add it to the nab item. So, each time you change the text you need to do a little dance by removing the view, resizing it and then adding it again. The key API is systemLayoutSizeFittingSize.