2010-08-31 41 views
3

我想要做什么:使用NSLayoutManager布局文本,并将它的NSTextContainer设置为字符串数组中最宽字符串的宽度(glyph-wise)。如何正确确定属性字符串的宽度

我的问题是:用于确定总“字形宽度”的方法似乎是不正确的,因为当我渲染文本时,它会打包。

我做了一个实验,使用32个字符的字符串与摩纳哥12点字体和长度报告为224.0,但文本将只停止包装如果长度设置为234.0。

此代码演示了我上面所说的内容,并在计算出的字形宽度的右侧显示了一条垂直线。

- (void)drawRect:(NSRect)rect { 
    NSRect bounds = [self bounds]; 

    [[NSColor whiteColor] drawSwatchInRect: bounds]; 
    [[NSColor blackColor] setStroke]; 
    [[NSBezierPath bezierPathWithRect: bounds] stroke]; 

    NSMutableParagraphStyle *thisParagraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; 
    [thisParagraphStyle setLineBreakMode: NSLineBreakByCharWrapping]; 
    [thisParagraphStyle setAlignment: NSLeftTextAlignment]; 

    NSFont *fontUsed = [NSFont fontWithName: @"Monaco" size: 12]; 

    NSDictionary *glyphAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
            fontUsed, NSFontAttributeName, 
            thisParagraphStyle, NSParagraphStyleAttributeName, 
            [NSColor blackColor], NSForegroundColorAttributeName, 
            NULL]; 

    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"00112233445566778899001122334455\n00112233445566778899001122334455\n00112233445566778899001122334455\n00112233445566778899001122334455\n"]; 

    [textStorage setAttributes: glyphAttributes range: NSMakeRange(0, [textStorage length])]; 

    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 

    NSSize textContainerSize; 
    textContainerSize.width = [@"00112233445566778899001122334455" sizeWithAttributes: glyphAttributes].width; 
    textContainerSize.height = bounds.size.height; 

    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize: textContainerSize]; 
    [layoutManager addTextContainer:textContainer]; 

    [textContainer release]; 
    [textStorage addLayoutManager:layoutManager]; 
    [layoutManager release]; 
    NSRange glyphRange = [layoutManager glyphRangeForTextContainer: textContainer]; 

    [layoutManager drawGlyphsForGlyphRange: glyphRange atPoint: NSMakePoint(0.0 , 0.0)]; 
    [textStorage release]; 
    [thisParagraphStyle release]; 

    // Indicate right text boundary from computed width 
    NSBezierPath *rightTextBoundary = [NSBezierPath bezierPath]; 
    [rightTextBoundary moveToPoint: NSMakePoint(textContainerSize.width, 0.0)]; 
    [rightTextBoundary lineToPoint: NSMakePoint(textContainerSize.width, bounds.size.height-1)]; 
    [rightTextBoundary stroke]; 

    NSLog(@"View width: %f", bounds.size.width); 
    NSLog(@"Calculated width1: %f", textContainerSize.width); 
    NSLog(@"Calculated width2: %f\n\n", [@"00112233445566778899001122334455" boundingRectWithSize: NSMakeSize(FLT_MAX, FLT_MAX) 
                     options: NSStringDrawingUsesDeviceMetrics 
                     attributes: glyphAttributes].size.width); 
} 

- (BOOL) isFlipped { 
    return YES; 
} 

回答

1

你看过这个类别的NSString和NSAttributedString NS(Attributed)String+Geometrics

如果它不是你正在寻找的东西,你可能会看到他们正在做的一些计算尺寸。