开发者

How can I tell NSTextField to autoresize it's font size to fit it's text? [duplicate]

开发者 https://www.devze.com 2023-01-08 21:56 出处:网络
This question already has answers here: Get NSTextField contents to scale 开发者_运维知识库(3 answers)
This question already has answers here: Get NSTextField contents to scale 开发者_运维知识库 (3 answers) Closed 8 years ago.

Looking for essentially whatever the Cocoa equivalent of [UILabel adjustsFontSizeToFitWidth] is.


I've solved it by creating a NSTextFieldCell subclass which overrides the string drawing. It looks whether the string fits and if it doesn't it decreases the font size until it does fit. This could be made more efficient and I have no idea how it'll behave when the cellFrame has a width of 0. Nevertheless it was Good Enough™ for my needs.

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    NSAttributedString *attributedString;
    NSMutableAttributedString *mutableAttributedString;
    NSSize stringSize;
    NSRect drawRect;

    attributedString = [self attributedStringValue];

    stringSize = [attributedString size];
    if (stringSize.width <= cellFrame.size.width) {
        // String is already small enough. Skip sizing.
        goto drawString;
    }

    mutableAttributedString = [attributedString mutableCopy];

    while (stringSize.width > cellFrame.size.width) {
        NSFont *font;

        font = [mutableAttributedString
            attribute:NSFontAttributeName
            atIndex:0
            effectiveRange:NULL
        ];
        font = [NSFont
            fontWithName:[font fontName]
            size:[[[font fontDescriptor] objectForKey:NSFontSizeAttribute] floatValue] - 0.5
        ];

        [mutableAttributedString
            addAttribute:NSFontAttributeName
            value:font
            range:NSMakeRange(0, [mutableAttributedString length])
        ];

        stringSize = [mutableAttributedString size];
    }

    attributedString = [mutableAttributedString autorelease];

drawString:
    drawRect = cellFrame;
    drawRect.size.height = stringSize.height;
    drawRect.origin.y += (cellFrame.size.height - stringSize.height) / 2;
    [attributedString drawInRect:drawRect];
}


Don't forget to look in superclasses. An NSTextField is a kind of NSControl, and every NSControl responds to the sizeToFit message.


I used Jerry Krinock's excellent NS(Attributed)String+Geometrics (located here) and a small method like the following. I'm still interested in a simpler way.

- (void) prepTextField:(NSTextField *)field withString:(NSString *)string
{   
    #define kMaxFontSize 32.0f
    #define kMinFontSize 6.0f
    float fontSize = kMaxFontSize;
    while (([string widthForHeight:[field frame].size.height font:[NSFont systemFontOfSize:fontSize]] > [field frame].size.width) && (fontSize > kMinFontSize))
    {
            fontSize--;
    }
    [field setFont:[NSFont systemFontOfSize:fontSize]];

    [field setStringValue:string];

    [self addSubview:field];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号