2017-06-16 25 views
0

我有多行NSTexField,用於顯示靜態文本,每個窗口顯示的長度可能不同。此NSTextField具有高度限制,將其限制爲兩行。NSTextField(多行)在填充所有行後水平增長

我想設置行爲,NSTextField只會水平增長,只會填滿那兩條水平線。 現在,當我將水平壓縮阻力設置得更高時,文本字段寬度會變得非常大,以便在一行上顯示所有文本。這隻能通過使用自動佈局約束來實現,還是必須以某種方式計算nstextfield的寬度?

我試着在superview中重載「layout」方法。但它沒有按照我的預期工作。

- (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]; 
      } 
     } 
    } 
} 

回答

0

我最終自己計算它。 我在NSTextField的子類中重載了setStringValue。 「PreferGrowingHorizo​​ntally」是一個子類屬性,如果我需要跳過此計算(例如:如果我希望它水平增長)

- (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; 
}