Как определить размер шрифта UILabel, когда -adjustsFontSizeToFitWidth установлен на YES?

Когда myLabel.adjustsFontSizeToFitWidth = YES, UILabel автоматически отрегулирует размер шрифта, если текст слишком длинный для метки. Например, если мой ярлык имеет ширину всего 100 пикселей, а мой текст слишком длинный, чтобы соответствовать текущему размеру шрифта, он уменьшит размер шрифта до тех пор, пока текст не будет помечен меткой.

Мне нужно получить фактический отображаемый размер шрифта от UILabel, когда размер шрифта уменьшился. Например, предположим, что размер моего шрифта был фактически 20, но UILabel пришлось сократить до 10. Когда я спрашиваю UILabel о шрифте и размере шрифта, я получаю свой старый размер шрифта (20), но не тот, который отображается (10).

Ответ 1

Я не уверен, что это абсолютно точно, но, надеюсь, должно быть довольно близко. Он может не учитывать усеченные строки или высоту метки, но это то, что вы могли бы сделать вручную.

Метод

- (CGSize) sizeWithFont: (UIFont *) font minFontSize: (CGFloat) minFontSize actualFontSize: (CGFloat *) actualFontSize forWidth: (CGFloat) width lineBreakMode: (UILineBreakMode) lineBreakMode

вернет размер текста и заметит, что он также имеет ссылочный параметр для фактического размера шрифта.

Ответ 2

Если кому-то еще нужен ответ. В iOS9 вы можете использовать boundingRectWithSize:options:context: для расчета фактического размера шрифта. Обратите внимание, что context.minimumScaleFactor не должен быть 0.0 для масштабирования для работы.

- (CGFloat)adjustedFontSizeForLabel:(UILabel *)label {
    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
    [text setAttributes:@{NSFontAttributeName:label.font} range:NSMakeRange(0, text.length)];

    NSStringDrawingContext *context = [NSStringDrawingContext new];
    context.minimumScaleFactor = label.minimumScaleFactor;
    [text boundingRectWithSize:label.frame.size options:NSStringDrawingUsesLineFragmentOrigin context:context];
    CGFloat adjustedFontSize = label.font.pointSize * context.actualScaleFactor;

    return adjustedFontSize;
}

Ответ 3

Для однострочного UILabel отлично работает это простое решение:

//myLabel - initial label

UILabel *fullSizeLabel = [UILabel new];
fullSizeLabel.font = myLabel.font;
fullSizeLabel.text = myLabel.text;
[fullSizeLabel sizeToFit];

CGFloat actualFontSize = myLabel.font.pointSize * (myLabel.bounds.size.width / fullSizeLabel.bounds.size.width);

//correct, if new font size bigger than initial
actualFontSize = actualFontSize < myLabel.font.pointSize ? actualFontSize : myLabel.font.pointSize;

Ответ 4

Swift 3

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    func adjustedFontSizeForLabel(_ label: UILabel) -> CGFloat {
        let text: NSMutableAttributedString = NSMutableAttributedString(attributedString: label.attributedText!)
        text.setAttributes([NSFontAttributeName: label.font], range: NSMakeRange(0, text.length))
        let context: NSStringDrawingContext = NSStringDrawingContext()
        context.minimumScaleFactor = label.minimumScaleFactor
        text.boundingRect(with: label.frame.size, options: NSStringDrawingOptions.usesLineFragmentOrigin, context: context)
        let adjustedFontSize: CGFloat = label.font.pointSize * context.actualScaleFactor
        return adjustedFontSize
    }

    print(adjustedFontSizeForLabel(yourLabel))
}