Objective C 视觉自动布局 NSTextField 动态高度

Objective C Visual Autolayout NSTextField dynamic height

我正在尝试使用视觉自动布局创建动态大小 NSView。我正在尝试实现类似下图的效果。

我添加了以下约束来实现这一点。

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-15-[_iconImageView(39)]-12-[_textView(239)]-15-|"
                                                             options:NSLayoutFormatAlignAllTop metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[_textView]-4-[_mainButton]-5-|"
                                                             options: NSLayoutFormatAlignAllLeft metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[_mainButton]-15-[_secondaryButton]"
                                                             options:NSLayoutFormatAlignAllTop metrics:nil views:views]];

但这会创建以下布局。

据我了解,下面的VFL会在距离_textView 15px的位置开始布局,然后在距离_textView底部4px的距离之后布局_mainButton。但实际上 _mainbottom 是在距离 _textView 顶部 4px 之后的布局。我在这里遗漏了什么吗?

@"V:|-15-[_textView]-4-[_mainButton]-5-|"

更新


我用 NSTextField 替换了 NSTextView。但是现在的问题是,NSTextField 不会增长超过单行高度,但是 NSTextField 是多行。布局和设置视图的完整代码如下。

-(void)setupView {
    _textField = [[NSTextField alloc] initWithFrame:NSZeroRect];
    [[_textField cell] setWraps:YES];
    [_textField setLineBreakMode:NSLineBreakByWordWrapping];
    [[_textField cell] setTitle:@"This is a _textView, This will contain dynamic resizing text."];

    [_textField setSelectable:NO];
    [_textField setEditable:NO];
    [_textField setDelegate:self];
    [_textField setBordered:NO];
    [_textField sizeToFit];
    [_textField setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self addSubview:_textField];
    
    _iconImageView = [[NSImageView alloc] initWithFrame:NSZeroRect];
    [_iconImageView setImage:[NSImage imageNamed:@"notify-warning-icon"]];
    [_iconImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self addSubview:_iconImageView];
    
    _mainButton = [[NSButton alloc] init];
    _mainButton.translatesAutoresizingMaskIntoConstraints = NO;
    [_mainButton setTitle:@"_mainButton"];
    [self addSubview:_mainButton];
    
    _secondaryButton = [[NSButton alloc] init];
    _secondaryButton.translatesAutoresizingMaskIntoConstraints = NO;
    [_secondaryButton setTitle:@"_secondaryButton"];
    [self addSubview:_secondaryButton];
    
    NSDictionary *views = NSDictionaryOfVariableBindings(_textField,_iconImageView,_mainButton,_secondaryButton);
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-15-[_iconImageView(39)]-12-[_textField(239)]-15-|"
                                                                 options:NSLayoutFormatAlignAllTop metrics:nil views:views]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[_textField]-4-[_mainButton]-5-|"
                                                                 options: NSLayoutFormatAlignAllLeft metrics:nil views:views]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[_mainButton]-15-[_secondaryButton]"
                                                                 options:NSLayoutFormatAlignAllTop metrics:nil views:views]];
    
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:0.f constant:320.f]];
}

但是如果它改变了这个

@"V:|-15-[_textField]-4-[_mainButton]-5-|"

有了这个

@"V:|-15-[_textField(>=40)]-4-[_mainButton]-5-|"

我得到以下输出

但问题是文本字段内容是动态的,可能会在运行时发生变化,它可能是 2 行、3 行等。那么我如何向 NSTextField 添加一些高度限制,这将改变 NSTextField 高度取决于其内容。

您可以使用文本字段而不是文本视图并设置其 preferredMaxLayoutWidth 属性。

默认情况下,如果 preferredMaxLayoutWidth 为 0,则文本字段将计算其固有大小,就好像其内容被布置在一长行中一样(或者至少没有任何最大宽度)。即使您应用限制其实际宽度的约束,也不会改变其固有高度,因此它通常不会高到足以包含换行的文本。

如果您设置 preferredMaxLayoutWidth,则文本字段将根据包裹到该宽度的文本计算其固有大小。这包括使其固有高度足够高以适应。