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];
}
精彩评论