NSTextField width and autolayout

I am trying to create an NSTextField programmatically.

I want to use this NSTextField with auto layout, so its width will be defined automatically to display the entire line (there is only one line of text).

The problem is that textField.intrinsicContentSize and textField.fittingSize are both have -1 and 0 values for the horizontal coordinate, as the output of the code below is: textField.intrinsicContentSize={-1, 21} textField.fittingSize={0, 21}

The code:

NSTextField* textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 10, 24)];    
NSString* str = @"One line of text here.";
[textField setStringValue: str];
[textField setTranslatesAutoresizingMaskIntoConstraints:NO];
[textField invalidateIntrinsicContentSize];

NSLog(@"textField.intrinsicContentSize=%@", NSStringFromSize(textField.intrinsicContentSize));
NSLog(@"textField.fittingSize=%@", NSStringFromSize(textField.fittingSize));

This makes the text field to have a zero width assigned by auto layout.

What should I do to get meaningful values for the fittingSize and intrinsicContentSize properties of the text field so they reflect the content of the text field?

Another way to compute the text field optimal width without using fittingSize is using the following code (replacing John Sauer's sizeTextFieldWidthToFit method):

- (void) sizeTextFieldWidthToFit {
    [textField sizeToFit];
    CGFloat newWidth = NSWidth(textField.frame);
    textFieldWidthConstraint.constant = newWidth;
}

You can set the priority of textFieldWidthConstraint to be lower than the priority of another inequality constrain the represent your requirement to a minimal size of 25.

How to let NSTextField grow with the text in auto layout?, Autolayout will grow and shrink the height of the text field if (a) you give the text field a preferredMaxLayoutWidth and (b) make the field not editable . These steps enable the text field to determine its intrinsic width and calculate the height needed for autolayout. I am trying to create an NSTextField programmatically. I want to use this NSTextField with auto layout, so its width will be defined automatically to display the entire line (there is only one lin

I can't explain why NSTextField's intrinsicContentSize's widths are -1, but I was able to calculate one based off its attributedString's size. Here's how I created the NSTextField:

// textField is an instance variable.
textField = [NSTextField new] ;
textField.translatesAutoresizingMaskIntoConstraints = NO ;
[view addSubview:textField] ;

NSDictionary* viewsDict = NSDictionaryOfVariableBindings(view, textField) ;
// textFieldWidthConstraint is an instance variable.
textFieldWidthConstraint  = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[textField(==0)]"  options:0  metrics:nil  views:viewsDict] [0] ;
[view addConstraint:textFieldWidthConstraint] ;
NSNumber* intrinsicHeight = @( textField.intrinsicContentSize.height ) ;
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[textField(==intrinsicHeight)]"  options:0  metrics:NSDictionaryOfVariableBindings(intrinsicHeight)  views:viewsDict]] ;

// Position textField however you like.
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[textField]"  options:0  metrics:nil  views:viewsDict]] ;
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[textField]"  options:0  metrics:nil  views:viewsDict]] ;

[self sizeTextFieldWidthToFit] ;
// set textField's delegate so that  sizeTextFieldWidthToFit  is called when textField's text changes.
textField.delegate = self ;

And here are the methods that resize it as its text changes:

- (void) controlTextDidChange:(NSNotification*)aNotification {
    if ( aNotification.object == textField )
        [self sizeTextFieldWidthToFit] ;
}

- (void) sizeTextFieldWidthToFit {
    // I'd like the width to always be >= 25.
    CGFloat newWidth = 25 ;
    if ( ! [textField.stringValue isEqualToString:@""] ) {
        NSDictionary* attributes = [textField.attributedStringValue  attributesAtIndex:0  effectiveRange:nil] ;
        NSSize size = [textField.stringValue sizeWithAttributes:attributes] ;
        newWidth =  MAX(newWidth, size.width + 10) ;
    }
    textFieldWidthConstraint.constant  = newWidth  ;
}

preferredTextFieldWidth, The preferred width is reflected in the cell's cellSize , which will be large enough to That is, under Auto Layout, the form will try to size itself so that the text field cell is However, for new apps, it's recommended that you use an NSTextField  edited Mar 24 '15 at 10:19 answered Jul 7 '14 at 20:58 hamstergene 17.9k 2 34 63 The width of the inspector is variable and is user controlled. It is not controlled (nor defined by) any constraints. Only the gray views and the NSTextField labels in the screenshots are using auto layout.

NSTextField intrinsicContentSize width is alway |Apple Developer , I've got a pair of editable text fields in a view using autolayout. (For completeness, these are inside an NSTableRowView in an editable table,  NSTextField And AutoLayout: Autogrow height-> Programmatically (2) If I create a label in interface builder and set a string through code that does not fit its current size, the label will grow vertically to fit its size, great!.

Auto-Growing NSTextField • Christian Tietze, Give it a >= trailing Auto Layout constraint so it can get smaller than the window,; Set the window's contentView 's width to a constant value,  Re: Making Autolayout respect NSWindow's maxSize.width Level 3 (385 points) Macho Man Randy Savage Sep 16, 2017 2:02 PM ( in response to Macho Man Randy Savage )

NSTextField width and autolayout - cocoa, I am trying to create an NSTextField programmatically. I want to use this NSTextField with auto layout, so its width will be defined automatically to display the  getting a NSTextField to grow with the text in auto layout? (5) I'm trying to get my NSTextField to have its height grow (much like in iChat or Adium) once the user types enough text to overflow the width of the control (as asked on this post) I've implimented the accepted answer yet I can't seem to get it to work.

NSTextField intrinsicContentSize is always returning, intrinsicContentSize} // Use intrinsic width to jive with autolayout let width = super.​intrinsicContentSize.width // Set the frame height to a reasonable number  The NSText Field class uses the NSText Field Cell class to implement its user interface.. The parent class, NSControl, provides the methods for setting the values of the text field, such as string Value and double Value.

Comments
  • This is solved here: stackoverflow.com/q/20809622/210171 (You must set editable = false for the text field to automatically size)
  • @nielsbot This only works if you never change the value of the text field. As soon as you programmatically alter the value of the text field, the text field collapses to -1 width. Setting constraints does not alter this. So what are we supposed to do then? This problem does not happen when using a text field that is in Interface Builder, only a text field initialized programmatically.
  • This works, but what's the point in using _auto_layout if you need to set the constraint manually?
  • Thanks. For computing the width manually I was able to use [textField sizeToFit] followed by getting the control frame width (which requires a much shorter code).
  • Could you post that code as an answer? Since it works and is much shorter, it should probably be the accepted answer.
  • Sorry, I didn't notice that only three lines in your solution are actually used to compute the optimal width, so eventually my solution is not much shorter, but I posted it anyway as a possible alternative.
  • It seems to me this answer is just a work around. What I'd like to know is how to have NSTextField intrinsicContentSize work as expected.