AppKit NSTextField and AutoLayout : how to set programmatically a specific width?

45 Views Asked by At

I'm porting my multi-platform C++ framework to the Mac, leveraging the AppKit in Objective C. Just like in Windows, I'm leveraging the auto layout capabilities of the host which works fine for buttons and labels. However, I have an issue with NSTextField initialized with textFieldWithString : the width of the text field is automatically set to the stack view's one, and not to the preferredMaxLayoutWidth.

Here's my test code (please note that my C++ framework keeps track of the host NSControl with pointers...)

NSStackView * hStackView = [ [ NSStackView alloc ] init ];
[ [ self window ] setContentView: hStackView ];
[ hStackView setOrientation: NSUserInterfaceLayoutOrientationVertical ];

UILabelPtr label = new UILabel( 'LBL0' );
label->SetLabel( new I18NString( ISOLanguageCode::English, "Login" ) );
label->SetTextWeight( TextWeightType::ExtraBold );

NSTextField * hTextField = ( __bridge NSTextField * ) label->GetHostUIElement();
[ hStackView addView:hTextField inGravity:NSStackViewGravityCenter ];

label = new UILabel( 'LBL1' );
label->SetLabel( new I18NString( ISOLanguageCode::English, "Please sign in to continue." ) );

hTextField = ( __bridge NSTextField * ) label->GetHostUIElement();
[ hStackView addView:hTextField inGravity:NSStackViewGravityCenter ];

UITextFieldPtr textField = new UITextField( 'USRD' );
textField->SetTextAlignment( TextAlignmentType::Center );
textField->SetPlaceholderText( new I18NString( ISOLanguageCode::English, "Email or account identifier" ) );

hTextField = ( __bridge NSTextField * ) textField->GetHostUIElement();
[ hTextField setPreferredMaxLayoutWidth: 200.0 ];
[ hStackView addView: hTextField inGravity: NSStackViewGravityCenter ];

UIPasswordFieldPtr passwordField = new UIPasswordField( 'PWRD' );
passwordField->SetTextAlignment( TextAlignmentType::Center );
passwordField->SetPlaceholderText( new I18NString( ISOLanguageCode::English, "Password" ) );

hTextField = ( __bridge NSTextField * ) passwordField->GetHostUIElement();
[ hTextField setPreferredMaxLayoutWidth: 200.0 ];
[ hStackView addView:hTextField inGravity:NSStackViewGravityCenter ];

UITextButtonPtr button = new UITextButton( 'LOGN' );
button->SetTitle( new I18NString( ISOLanguageCode::English, "Login" ) );

NSButton * hButton = ( __bridge NSButton * ) button->GetHostUIElement();
[ hStackView addView:hButton inGravity:NSStackViewGravityCenter ];

Here's the resulting window:

Actual screenshot of my test window

Question: how can I force the NSTextField's width to a max value while leveraging the auto layout feature of the NSStackView ?

PS: The NSControl connected to my UILabel class is created with hLabel = [ NSTextField labelWithString: @"" ], while the one connected to my UITextField class is created with hTextField = [ NSTextField textFieldWithString: @"" ].

1

There are 1 best solutions below

0
alphafox75 On

Going through the StackOverflow archives, I managed to force the NSTextField width with the following code:

NSNumber * preferredWidth = @( 200.0 );
[ hStackView addConstraints: [ NSLayoutConstraint constraintsWithVisualFormat: @"H:[hTextField(==preferredWidth)]"
    options: 0
    metrics: NSDictionaryOfVariableBindings( preferredWidth )
    views: NSDictionaryOfVariableBindings( hStackView, hTextField ) ] ];