Skip to content

Instantly share code, notes, and snippets.

@plumhead
Created September 15, 2015 13:34
Show Gist options
  • Star 84 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save plumhead/945e0f2945a3ffea378a to your computer and use it in GitHub Desktop.
Save plumhead/945e0f2945a3ffea378a to your computer and use it in GitHub Desktop.
String extension to find the layout size of a String with specified attributes.
extension String {
func size(withAttributes attrs: [String:AnyObject], constrainedTo box: NSSize) -> NSRect {
let storage = NSTextStorage(string: self)
let container = NSTextContainer(containerSize: NSSize(width: box.width, height: box.height))
let layout = NSLayoutManager()
layout.addTextContainer(container)
storage.addLayoutManager(layout)
storage.addAttributes(attrs, range: NSMakeRange(0, storage.length))
container.lineFragmentPadding = 0.0
let _ = layout.glyphRangeForTextContainer(container)
return layout.usedRectForTextContainer(container)
}
}
@plumhead
Copy link
Author

Use as follows

  • let s = "This is a string for testing the size with attributes and constrained to string extension."
  • let size = s.size(withAttributes: [NSFontAttributeName:NSFont.systemFontOfSize(20)], constrainedTo: NSSize(width: 60, height: Int.max))

@plumhead
Copy link
Author

Obviously you could extend to pass a function in to configure the text container rather than simply setting a default lineFragmentPaddding as the example shows.

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