Skip to content

Instantly share code, notes, and snippets.

@gnou
Created March 21, 2017 10:09
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save gnou/52bd2f31e99c9311ffa0eb0183ac7cfd to your computer and use it in GitHub Desktop.
Save gnou/52bd2f31e99c9311ffa0eb0183ac7cfd to your computer and use it in GitHub Desktop.
Calculate height of some text when width is fixed
public struct TextSize {
fileprivate struct CacheEntry: Hashable {
let text: String
let font: UIFont
let width: CGFloat
let insets: UIEdgeInsets
fileprivate var hashValue: Int {
return text.hashValue ^ Int(width) ^ Int(insets.top) ^ Int(insets.left) ^ Int(insets.bottom) ^ Int(insets.right)
}
}
fileprivate static var cache = [CacheEntry: CGRect]() {
didSet {
assert(Thread.isMainThread)
}
}
public static func size(_ text: String, font: UIFont, width: CGFloat, insets: UIEdgeInsets = UIEdgeInsets.zero) -> CGRect {
let key = CacheEntry(text: text, font: font, width: width, insets: insets)
if let hit = cache[key] {
return hit
}
let constrainedSize = CGSize(width: width - insets.left - insets.right, height: CGFloat.greatestFiniteMagnitude)
let attributes = [ NSFontAttributeName: font ]
let options: NSStringDrawingOptions = [.usesFontLeading, .usesLineFragmentOrigin]
var bounds = (text as NSString).boundingRect(with: constrainedSize, options: options, attributes: attributes, context: nil)
bounds.size.width = width
bounds.size.height = ceil(bounds.height + insets.top + insets.bottom)
cache[key] = bounds
return bounds
}
}
private func ==(lhs: TextSize.CacheEntry, rhs: TextSize.CacheEntry) -> Bool {
return lhs.width == rhs.width && lhs.insets == rhs.insets && lhs.text == rhs.text
}
@seyoung-hyun
Copy link

Thanks your code :)
Can I use your code in my commercial app?
Please let me know how I can use the code for commercial distribution.

@gnou
Copy link
Author

gnou commented Aug 16, 2019

yes, you can use it in any way you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment