Масштабирование размера шрифта по вертикали в UILabel
Я хочу взять стандартную UILabel и увеличить размер шрифта, чтобы он заполнил вертикальное пространство. Воспользовавшись принятым ответом на этот question, я определил подкласс в UILabel с этой реализацией drawRect:
- (void)drawRect:(CGRect)rect
{
// Size required to render string
CGSize size = [self.text sizeWithFont:self.font];
// For current font point size, calculate points per pixel
float pointsPerPixel = size.height / self.font.pointSize;
// Scale up point size for the height of the label
float desiredPointSize = rect.size.height * pointsPerPixel;
// Create and assign new UIFont with desired point Size
UIFont *newFont = [UIFont fontWithName:self.font.fontName size:desiredPointSize];
self.font = newFont;
// Call super
[super drawRect:rect];
}
Но это не работает, поскольку он масштабирует шрифт за пределами нижней метки. Если вы хотите воспроизвести это, я начал с метки 289x122 (w x h), Helvetica в качестве шрифта и начальной точки. Размер 60, который удобно помещается на этикетке. Вот пример вывода из стандартного UILabel и моего подкласса с использованием строки "{Hg":
![uilabel]()
![uilabel subclass]()
Я посмотрел на шрифты descenders и ascenders, попробовал масштабирование, принимая их во внимание в разных комбинациях, но до сих пор не повезло. Любые идеи, это что-то общее с разными шрифтами, имеющими различную длину спуска и восхождения?
Ответы
Ответ 1
Ваш расчет для pointsPerPixel
неверный путь вверх, он должен быть...
float pointsPerPixel = self.font.pointSize / size.height;
Кроме того, возможно, этот код должен быть в layoutSubviews
, поскольку единственный раз, когда шрифт должен быть изменен, это когда размер кадра изменяется.
Ответ 2
Интересно, имеет ли округление ошибку, приближающуюся к следующему большему размеру шрифта. Не могли бы вы просто масштабировать rec.size.height немного? Что-то вроде:
float desiredPointSize = rect.size.height *.90 * pointsPerPixel;
Обновление: Ваш расчет pointPerPixel обратный. Вы фактически делят пиксели точками шрифта, а не точками на пиксели. Меняйте их, и он работает каждый раз. Просто для тщательности, здесь образец кода, который я тестировал:
//text to render
NSString *soString = [NSString stringWithFormat:@"{Hg"];
UIFont *soFont = [UIFont fontWithName:@"Helvetica" size:12];
//box to render in
CGRect rect = soLabel.frame;
//calculate number of pixels used vertically for a given point size.
//We assume that pixel-to-point ratio remains constant.
CGSize size = [soString sizeWithFont:soFont];
float pointsPerPixel;
pointsPerPixel = soFont.pointSize / size.height; //this calc works
//pointsPerPixel = size.height / soFont.pointSize; //this calc does not work
//now calc which fontsize fits in the label
float desiredPointSize = rect.size.height * pointsPerPixel;
UIFont *newFont = [UIFont fontWithName:@"Helvetica" size:desiredPointSize];
//and update the display
[soLabel setFont:newFont];
soLabel.text = soString;
Это масштабируется и помещается внутри ящика для каждого размера, который я тестировал, от 40 до 60 пикселей шрифтов. Когда я отменил вычисление, я увидел те же результаты, когда шрифт был слишком высоким для поля.