我正在尝试以编程方式创建NSTextField
。
我想将此NSTextField
用于自动布局,因此其宽度将自动定义以显示整行(只有一行文字)。
问题是textField.intrinsicContentSize
和textField.fittingSize
都有水平坐标的-1和0值,因为下面代码的输出是:
textField.intrinsicContentSize={-1, 21}
textField.fittingSize={0, 21}
代码:
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));
这使得文本字段具有由自动布局指定的零宽度。
如何为文本字段的fittingSize
和intrinsicContentSize
属性获取有意义的值,以便它们反映文本字段的内容?
答案 0 :(得分:6)
在不使用fittingSize
的情况下计算文本字段最佳宽度的另一种方法是使用以下代码(替换John Sauer的sizeTextFieldWidthToFit方法):
- (void) sizeTextFieldWidthToFit {
[textField sizeToFit];
CGFloat newWidth = NSWidth(textField.frame);
textFieldWidthConstraint.constant = newWidth;
}
您可以将textFieldWidthConstraint的优先级设置为低于另一个不等式约束的优先级,将您的要求表示为最小值25。
答案 1 :(得分:2)
我无法解释为什么NSTextField的intrinsicContentSize的宽度为-1,但我能够根据其attributesString的大小计算出一个。这是我创建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 ;
以下是在文本更改时调整大小的方法:
- (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 ;
}
答案 2 :(得分:0)
我在这里添加这个是因为这些答案都很老了,我找不到让NSTextField
在一个答案中使用autolayout和NSConstraints自动换行和播放所需的一切。
使用这些设置,文本将:
这是让它正常工作的代码:
NSTextField *instructions = [NSTextField labelWithString:@"Some very long text..."];
instructions.translatesAutoresizingMaskIntoConstraints = NO;
instructions.autoresizesSubviews = YES;
instructions.usesSingleLineMode = NO;
instructions.lineBreakMode = NSLineBreakByWordWrapping;
[instructions cell].wraps = YES;
[instructions cell].scrollable = NO;
instructions.maximumNumberOfLines = 10;
instructions.preferredMaxLayoutWidth = 400.0;
[self addSubview:iCloudInstructions];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[instructions]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(instructions)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[instructions]-(20)-[button]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(instructions, instructions)]];