Skip to content

Instantly share code, notes, and snippets.

@vladimir-bebeshko
Forked from joncardasis/UIFont+BestFit.swift
Created December 8, 2018 12:02
Show Gist options
  • Save vladimir-bebeshko/46ce0438ff98cfc2c041435254230d0d to your computer and use it in GitHub Desktop.
Save vladimir-bebeshko/46ce0438ff98cfc2c041435254230d0d to your computer and use it in GitHub Desktop.
Swift Dynamic Font Size for Bounds
extension UIFont {
/**
Will return the best font conforming to the descriptor which will fit in the provided bounds.
*/
static func bestFittingFontSize(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor, additionalAttributes: [NSAttributedStringKey: Any]? = nil) -> CGFloat {
let constrainingDimension = min(bounds.width, bounds.height)
let properBounds = CGRect(origin: .zero, size: bounds.size)
var attributes = additionalAttributes ?? [:]
let infiniteBounds = CGSize(width: CGFloat.infinity, height: CGFloat.infinity)
var bestFontSize: CGFloat = constrainingDimension
for fontSize in stride(from: bestFontSize, through: 0, by: -1) {
let newFont = UIFont(descriptor: fontDescriptor, size: fontSize)
attributes[.font] = newFont
let currentFrame = text.boundingRect(with: infiniteBounds, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil)
if properBounds.contains(currentFrame) {
bestFontSize = fontSize
break
}
}
return bestFontSize
}
static func bestFittingFont(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor, additionalAttributes: [NSAttributedStringKey: Any]? = nil) -> UIFont {
let bestSize = bestFittingFontSize(for: text, in: bounds, fontDescriptor: fontDescriptor, additionalAttributes: additionalAttributes)
return UIFont(descriptor: fontDescriptor, size: bestSize)
}
}
extension UILabel {
/// Will auto resize the contained text to a font size which fits the frames bounds.
/// Uses the pre-set font to dynamically determine the proper sizing
func fitTextToBounds() {
guard let text = text, let currentFont = font else { return }
let bestFittingFont = UIFont.bestFittingFont(for: text, in: bounds, fontDescriptor: currentFont.fontDescriptor, additionalAttributes: basicStringAttributes)
font = bestFittingFont
}
private var basicStringAttributes: [NSAttributedStringKey: Any] {
var attribs = [NSAttributedStringKey: Any]()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = self.textAlignment
paragraphStyle.lineBreakMode = self.lineBreakMode
attribs[.paragraphStyle] = paragraphStyle
return attribs
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment