【问题标题】:How to optimally fit a NSString in a rectangle? [duplicate]如何以最佳方式将 NSString 适合矩形? [复制]
【发布时间】:2010-12-29 00:27:30
【问题描述】:

可能重复:
Change NSTextField font size to fit

我试图在给定的矩形内放置一个可变长度的字符串(字符串中的单词数未知)。我想优化字符串的大小,使其尽可能大并适合矩形。此外,如果有多个单词并且一个单词不应部分呈现在多行上,则字符串应该自动换行。我的问题有时是一个单词部分排列在多行上,如下所示。关于我可能做错的任何建议?

谢谢。

我正在使用 NSLayoutManager、NSTextStorage 和 NSTextContainer。

我按如下方式初始化所有内容:

    textStorage = [[NSTextStorage alloc] initWithString:@""];
    layoutManager = [[NSLayoutManager alloc] init];
    textContainer = [[NSTextContainer alloc] init];

    [layoutManager addTextContainer:textContainer];     
    [textStorage addLayoutManager:layoutManager];   

    paraStyle = [[NSMutableParagraphStyle alloc] init];
    [paraStyle setLineBreakMode:NSLineBreakByWordWrapping];
    [paraStyle setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]];
    [paraStyle setAlignment:NSCenterTextAlignment];

然后我计算字体大小如下,

- (float)calculateFontSizeForString:(NSString *)aString andBoxSize:(NSSize)aBox
{
    //Create the attributed string
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:aString];
    [textStorage setAttributedString:attrString];
    [textContainer setContainerSize:NSMakeSize(aBox.width, FLT_MAX)];   
    [attrString release]; //Clean up

    //Initial values
    float fontSize = 50.0;
    float fontStepSize = 100.0;
    NSRect stringRect;
    BOOL didFindHeight = NO;
    BOOL shouldIncreaseHeight = YES;

    while (!didFindHeight)
    {   
        NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                                 paraStyle, NSParagraphStyleAttributeName,
                                                 [NSFont systemFontOfSize:fontSize], NSFontAttributeName, nil];

        [textStorage addAttributes:stringAttributes range:NSMakeRange(0, [textStorage length])];

        (void)[layoutManager glyphRangeForTextContainer:textContainer];     
        stringRect = [layoutManager usedRectForTextContainer:textContainer];

        if (shouldIncreaseHeight)
        {
            if (stringRect.size.height > aBox.height)
            {
                shouldIncreaseHeight = NO;
                fontStepSize = fontStepSize/2;
            }

            fontSize += fontStepSize;
        }
        else
        {
            if (stringRect.size.height < aBox.height)
            {
                shouldIncreaseHeight = YES;

                fontStepSize = fontStepSize/2;

                if (fontStepSize <= 0.5)
                {
                    didFindHeight = YES;
                }
            }

            if ((fontSize - fontStepSize) <= 0)
            {
                fontStepSize = fontStepSize/2;              
            }
            else
            {
                fontSize -= fontStepSize;
            }
        }
    }

    return fontSize;
}

【问题讨论】:

    标签: cocoa macos nsstring


    【解决方案1】:

    发帖前请先搜索。这反复出现。最新答案是here,但我认为其他地方的代码清单有更完整的答案。

    我公认的简单示例展示了如何在没有文本容器和布局管理器的情况下执行此操作,但您的方法更健壮。不幸的是,蛮力(缩小尺寸直到合适)是确定最佳拟合的唯一方法。

    【讨论】:

      猜你喜欢
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多