У меня есть представление, которое содержит два NSTextFieldCell
s. Размер, в котором оттянуты эти ячейки, получен из размера представления, и я хочу, чтобы текст в каждой ячейке был самым большим, который поместится в полученный размер ячейки. Вот то, что я имею, который не устанавливает размер шрифта:
- (void)drawRect:(NSRect)dirtyRect {
/*
* Observant readers will notice that I update the whole view here. If
* there is a perceived performance problem, then I'll switch to just
* updating the dirty rect.
*/
NSRect boundsRect = self.bounds;
const CGFloat monthHeight = 0.25 * boundsRect.size.height;
NSRect monthRect = NSMakeRect(boundsRect.origin.x,
boundsRect.origin.y + boundsRect.size.height
- monthHeight,
boundsRect.size.width,
monthHeight);
[monthCell drawWithFrame: monthRect inView: self];
NSRect dayRect = NSMakeRect(boundsRect.origin.x,
boundsRect.origin.y,
boundsRect.size.width,
boundsRect.size.height - monthHeight);
[dayCell drawWithFrame: dayRect inView: self];
[[NSColor blackColor] set];
[NSBezierPath strokeRect: boundsRect];
}
Таким образом, я знаю, что могу спросить строку, какой размер она взяла бы для данных атрибутов, и я знаю, что могу попросить, чтобы управление изменило свой размер для установки его содержанию. Ни один из тех не кажется применимым: Я хочу содержание (в этом случае, ячейка stringValue
) к размеру для установки известному реагируют, размеры, с атрибутами должны были достигнуть того являющегося неизвестным. Как я могу найти необходимый размер? Предположите, что я знаю, какой шрифт я буду использовать (потому что я делаю).
Примечание обновления: Я не хочу усекать строку, я хочу вырастить или уменьшить ее так, чтобы все это соответствовало с самым большим возможным размером текста, в обеспеченный реагируют.
Я использую похожий код, но он работает с различными шрифтами, размером до 10 000 и учитывает доступную высоту и ширину области, в которой отображается текст.
#define kMaxFontSize 10000
- (CGFloat)fontSizeForAreaSize:(NSSize)areaSize withString:(NSString *)stringToSize usingFont:(NSString *)fontName;
{
NSFont * displayFont = nil;
NSSize stringSize = NSZeroSize;
NSMutableDictionary * fontAttributes = [[NSMutableDictionary alloc] init];
if (areaSize.width == 0.0 || areaSize.height == 0.0) {
return 0.0;
}
NSUInteger fontLoop = 0;
for (fontLoop = 1; fontLoop <= kMaxFontSize; fontLoop++) {
displayFont = [[NSFontManager sharedFontManager] convertWeight:YES ofFont:[NSFont fontWithName:fontName size:fontLoop]];
[fontAttributes setObject:displayFont forKey:NSFontAttributeName];
stringSize = [stringToSize sizeWithAttributes:fontAttributes];
if (stringSize.width > areaSize.width)
break;
if (stringSize.height > areaSize.height)
break;
}
[fontAttributes release], fontAttributes = nil;
return (CGFloat)fontLoop - 1.0;
}
Было рекомендовано вне диапазона попробовать двоичный поиск подходящего размера. Это очень ограниченный пример:
- (NSFont *)labelFontForText: (NSString *)text inRect: (NSRect)rect {
CGFloat prevSize = 0.0, guessSize = 16.0, tempSize;
NSFont *guessFont = nil;
while (fabs(guessSize - prevSize) > 0.125) {
guessFont = [NSFont labelFontOfSize: guessSize];
NSSize textSize = [text sizeWithAttributes:
[NSDictionary dictionaryWithObject: guessFont
forKey: NSFontAttributeName]];
if (textSize.width > rect.size.width ||
textSize.height > rect.size.height) {
tempSize = guessSize - (guessSize - prevSize) / 2.0;
}
else {
tempSize = guessSize + (guessSize - prevSize) / 2.0;
}
prevSize = guessSize;
guessSize = tempSize;
}
return [[guessFont retain] autorelease];
}
Ограничения (вам лучше не нужен шрифт 32pt или больше, или что-нибудь, кроме Lucida Grande) не важны для моих нужд, но, безусловно, оттолкнут некоторых людей используя этот метод. Я оставлю вопрос открытым и приму более здравый подход.
Две идеи. Один я пробовал, другой может сработать:
1) Сделайте как в этом вопросе: Как обрезать NSString на основе графической ширины? т.е. просто попробуйте разные размеры, пока он не перестанет работать. fit anymore
2) Создайте ячейку, дайте ей максимальный прямоугольник и установите его так, чтобы текст помещался в ячейку, затем спросите ее идеальный размер (там есть метод, который это делает), затем снова измените размер ячеек. Наконец-то, если я правильно понял вашу проблему.