Question

I’m trying to put together what seems to be a simple case of two NSTextFields with dynamic width and fixed spacing in between. I cannot figure out an effective way to do so though.

I’m looking to get something like this:

Goal

The blue boxes are the NSTextFields. When more text is entered into one, it should grow and thus make the other one shrink, maintaining the lead space, trailing space and the spacing in between the fields. The first one should take the priority if both of the fields have too much text. Each field will also clearly have a maximum and a minimum possible width it can reach.

Examples

How would I go around handling this, preferably utilising IB autolayout as much as possible?

Was it helpful?

Solution

It seems to me that all of constraints you mentioned directly translate into interface builder --

  1. First view has width >= something.
  2. First view has width <= something
  3. Same for Second view.
  4. Space between views is fixed.
  5. Second view wants to be as small as possible (have its width at 0) but this has lower lower priority than the previous constraints and lower priority than inner content size constraints.

OTHER TIPS

The code I had to add to my view controller, after applying the constraints as per the ilya’s answer:

In controlTextDidChange (_controlWidthConstraint refers to the fixed width constraint of the input; it’s probably 0 by default for the second input):

// Get the new width that fits
float oldWidth = textControl.frame.size.width;
[input sizeToFit];
float controlWidth = textControl.frame.size.width;

// Don’t let the sizeToFit method modify the frame though
NSRect controlRect = textControl.frame;
controlRect.size.width = oldWidth;
textControl.frame = controlRect;

_controlWidthConstraint.constant = controlWidth;

The key lies in invalidating the intrinsicContentSize for the text field when text is input.

You can check a sample project here, to get you on the right track.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top