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

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

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

4 ответа

Решение

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

Метод

- (CGSize)sizeWithFont:(UIFont *) шрифт minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat) ширина lineBreakMode:(UILineBreakMode)lineBreakMode

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

В случае, если кому-то все еще нужен ответ. В 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;
}

Для однострочного 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;

Swift 5

Для однострочного UILabel

extension UILabel {

    var actualFontSize: CGFloat {
    //initial label
     let fullSizeLabel = UILabel()
     fullSizeLabel.font = self.font
     fullSizeLabel.text = self.text
     fullSizeLabel.sizeToFit()

     var actualFontSize: CGFloat = self.font.pointSize * (self.bounds.size.width / fullSizeLabel.bounds.size.width);

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

     return actualFontSize
    }

}

Тогда получить фактический размер шрифта очень просто:

let currentLabelFontSize = myLabel.actualFontSize
UILabel *txtLabel = [[UILabel alloc] initWithFrame:rectMax];
txtLabel.numberOfLines = 1;
txtLabel.font = self.fontMax;
txtLabel.adjustsFontSizeToFitWidth = YES;
txtLabel.minimumScaleFactor = 0.1;
[txtLabel setText:strMax];

UILabel *fullSizeLabel = [UILabel new];
fullSizeLabel.font = txtLabel.font;
fullSizeLabel.text = txtLabel.text;
fullSizeLabel.numberOfLines = 1;
[fullSizeLabel sizeToFit];

CGFloat actualFontSize = txtLabel.font.pointSize * (txtLabel.bounds.size.width / fullSizeLabel.bounds.size.width);
actualFontSize = actualFontSize < txtLabel.font.pointSize ? actualFontSize : txtLabel.font.pointSize;
// the actual font
self.fontMax = [UIFont fontWithName:self.fontMax.fontName size:actualFontSize];

мой код отлично работает, часть от @Igor

Свифт 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))
}
Другие вопросы по тегам