Skip to content

Instantly share code, notes, and snippets.

@astrokin
Last active April 14, 2018 20:16
Show Gist options
  • Save astrokin/02c787a52eda4c771a98c62e55efad77 to your computer and use it in GitHub Desktop.
Save astrokin/02c787a52eda4c771a98c62e55efad77 to your computer and use it in GitHub Desktop.
FontFitUtil
import Foundation
class FontFitUtil {
class func bestFontForText(_ text: String, font: UIFont, container: UIView) -> UIFont {
return bestFontForText(text, font: font, container: container.bounds.size)
}
class func bestFontForText(_ text: String, font: UIFont, container: CGSize) -> UIFont {
//make rect to calculate text a little bit smaller
guard container != CGSize.zero else { return font }
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = .byWordWrapping
let boundingBox = text.boundingRect(with: CGSize(width: container.width, height: CGFloat.greatestFiniteMagnitude),
options: [.usesLineFragmentOrigin, .usesFontLeading],
attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.paragraphStyle: paragraph],
context: nil)
if boundingBox.height > container.height {
return bestFontForText(text, font: font.adding(points: -1), container: container)
} else {
return font
}
}
///manually calculate best to fit font size for textfields
class func updateTextFieldFont(_ textField: UITextField) {
guard let text = textField.text else { return }
textField.layoutIfNeeded()
let maxFont = UIFont(descriptor: Font.title.uiFont().fontDescriptor, size: maxFontSizeToStartScaling())
let resultFont = bestFontForText(text, font: maxFont, container: textField.bounds.size)
textField.font = resultFont
}
///manually calculate best to fit font size for textfields
class func updateSystemFontLabel(_ label: UILabel) {
guard let text = label.text else { return }
label.layoutIfNeeded()
let maxFont = UIFont(descriptor: UIFont.systemFont(ofSize: maxFontSizeToStartScaling(fontWeight: .ultraLight), weight: .ultraLight).fontDescriptor,
size: maxFontSizeToStartScaling(fontWeight: .ultraLight))
let resultFont = bestFontForText(text, font: maxFont, container: label.bounds.size)
label.font = resultFont
}
class func maxFontSizeToStartScaling(fontWeight: UIFont.Weight? = nil) -> CGFloat {
if let weight = fontWeight {
if weight == .ultraLight {
return 60
}
}
if LayoutBuilder.isExtraExtraLargeCategory || LayoutBuilder.isExtraLargeCategory {
return 40
}
if LayoutBuilder.isLargeCategory {
return 32
}
if LayoutBuilder.isMediumCategory {
return 24
}
return 20
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment