NSTextField(多行)在填充所有行后水平增长



>我有多行NSTexField,我用它来显示静态文本,每次显示窗口时可能有不同的长度。此 NSTextField 具有高度约束,将其限制为两条线。

我想设置行为,即 NSTextField 将水平增长仅如此之多,以至于它将填充这两条水平线。 现在,当我将水平压缩阻力设置得更高时,文本字段宽度会增长很多,以便在一行上显示所有文本。这是否可以仅通过使用自动布局约束来实现,或者我是否必须以某种方式计算 nstext字段宽度?

我尝试在超级视图中重载"布局"方法。但它没有像我预期的那样工作。

- (void)layout
{
[self solveLayoutForView:self];
}
- (void)solveLayoutForView:(NSView*)view
{
for (NSView* subView in [view subviews])
{
if (subView.subviews.count)
[self solveLayoutForView:subView];
else
{
NSLayoutConstraint* height = [subView constraintForAttribute:NSLayoutAttributeHeight];
if (height && height.constant > 17 && [subView isKindOfClass:[NSTextField class]]) // seems like multiline nstextfield
{
NSTextField* textField = (NSTextField*)subView;
textField.preferredMaxLayoutWidth = 0;
[super layout];
textField.preferredMaxLayoutWidth = NSWidth([textField alignmentRectForFrame:textField.frame]);
[super layout];
}
}
}
}

我最终自己计算了它。 我在NSTextField的子类中重载setStringValue。 "PreferGrowHorizontally"是一个子类属性,如果我需要跳过这个计算(例如:如果我希望它水平增长)

- (void)setStringValue:(NSString *)stringValue
{
BOOL changed = ![self.stringValue isEqualToString:stringValue] ? YES : NO;
[super setStringValue:stringValue];
if (stringValue.length && changed)
{
if (self.frame.size.height > 17 && self.preferGrowingHorizontally)
[self compensateWidth];
}
}
- (void)compensateWidth
{
float requiredHeight = FLT_MAX;
int widthCompensation = 0;
while (requiredHeight > self.frame.size.height)
requiredHeight = [self heightForStringDrawing:self.stringValue Font:self.font Width:self.frame.size.width + widthCompensation++];
if (--widthCompensation)
{
NSLayoutConstraint* width = [self constraintForAttribute:NSLayoutAttributeWidth];
if (width)
width.constant = self.frame.size.width + widthCompensation;
NSLog(@"requiredHeight: %f width compensation: %d for textField: %@", requiredHeight, widthCompensation, self.stringValue);
}
}
- (float)heightForStringDrawing:(NSString*)myString Font:(NSFont*)myFont Width:(float)myWidth
{
NSTextStorage *textStorage = [[[NSTextStorage alloc] initWithString:myString] autorelease];
NSTextContainer *textContainer = [[[NSTextContainer alloc] initWithContainerSize:NSMakeSize(myWidth, FLT_MAX)] autorelease];
NSLayoutManager *layoutManager = [[[NSLayoutManager alloc] init] autorelease];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
[textStorage addAttribute:NSFontAttributeName value:myFont
range:NSMakeRange(0, [textStorage length])];
[textContainer setLineFragmentPadding:0.0];
textContainer.lineBreakMode = NSLineBreakByWordWrapping;
(void) [layoutManager glyphRangeForTextContainer:textContainer];
return [layoutManager usedRectForTextContainer:textContainer].size.height;
}

最新更新