Skip to content

Instantly share code, notes, and snippets.

@joncardasis
Last active January 31, 2020 22:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joncardasis/30acd0235e575b8661a66517989bdfc9 to your computer and use it in GitHub Desktop.
Save joncardasis/30acd0235e575b8661a66517989bdfc9 to your computer and use it in GitHub Desktop.
[DEPRECATED] Swift Dynamic Font Size for Bounds
import UIKit
extension UIFont {
/**
Will return the best approximated font size which will fit in the bounds.
If no font with name `fontName` could be found, nil is returned.
*/
static func bestFitFontSize(for text: String, in bounds: CGRect, fontName: String) -> CGFloat? {
var maxFontSize: CGFloat = 32.0 // UIKit best renders with factors of 2
guard let maxFont = UIFont(name: fontName, size: maxFontSize) else {
return nil
}
let textWidth = text.width(withConstraintedHeight: bounds.height, font: maxFont)
let textHeight = text.height(withConstrainedWidth: bounds.width, font: maxFont)
// Determine the font scaling factor that should allow the string to fit in the given rect
let scalingFactor = min(bounds.width / textWidth, bounds.height / textHeight)
// Adjust font size
maxFontSize *= scalingFactor
return floor(maxFontSize)
}
}
fileprivate extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.height)
}
func width(withConstraintedHeight height: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.width)
}
}
extension UILabel {
/// Will auto resize the contained text to a font size which fits the frames bounds
/// Uses the pre-set font to dynamicly determine the proper sizing
func fitTextToBounds() {
guard let text = text, let currentFont = font else { return }
if let dynamicFontSize = UIFont.bestFitFontSize(for: text, in: bounds, fontName: currentFont.fontName) {
font = UIFont(name: currentFont.fontName, size: dynamicFontSize)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment