Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get auto-adjusted font size in iOS 7.0 or later?

Tags:

ios

uikit

I want to get the font size of some text after it's been scaled down in a UILabel or UITextField. This was possible before iOS 7.0: How to get UILabel (UITextView) auto adjusted font size?. However, sizeWithFont has been deprecated in iOS 7.0. I've tried using its replacement, sizeWithAttributes, but with no success. Is there any way to do this in iOS 7.0?

like image 616
WaltersGE1 Avatar asked Feb 02 '15 18:02

WaltersGE1


2 Answers

Swift 4

The answers above work well, but use some deprecated values/functions. Here's a fixed version that works in 2018.

func approximateAdjustedFontSizeWithLabel(_ label: UILabel) -> CGFloat {
    var currentFont: UIFont = label.font
    let originalFontSize = currentFont.pointSize
    var currentSize: CGSize = (label.text! as NSString).size(withAttributes: [NSAttributedStringKey.font: currentFont])

    while currentSize.width > label.frame.size.width && currentFont.pointSize > (originalFontSize * label.minimumScaleFactor) {
        currentFont = currentFont.withSize(currentFont.pointSize - 1.0)
        currentSize = (label.text! as NSString).size(withAttributes: [NSAttributedStringKey.font: currentFont])
    }

    return currentFont.pointSize
}
like image 88
jab Avatar answered Sep 27 '22 15:09

jab


I really liked @WaltersGE1's answer, so I made it into an extension for UILabel to make it even more convenient to use:

extension UILabel {

    /// The receiver’s font size, including any adjustment made to fit to width. (read-only)
    ///
    /// If `adjustsFontSizeToFitWidth` is not `true`, this is just an alias for
    /// `.font.pointSize`. If it is `true`, it returns the adjusted font size.
    ///
    /// Derived from: [http://stackoverflow.com/a/28285447/5191100](http://stackoverflow.com/a/28285447/5191100)
    var fontSize: CGFloat {
        get {
            if adjustsFontSizeToFitWidth {
                var currentFont: UIFont = font
                let originalFontSize = currentFont.pointSize
                var currentSize: CGSize = (text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])

                while currentSize.width > frame.size.width && currentFont.pointSize > (originalFontSize * minimumScaleFactor) {
                    currentFont = currentFont.fontWithSize(currentFont.pointSize - 1)
                    currentSize = (text! as NSString).sizeWithAttributes([NSFontAttributeName: currentFont])
                }

                return currentFont.pointSize
            }

            return font.pointSize
        }
    }
}
like image 30
dbburgess Avatar answered Sep 27 '22 15:09

dbburgess