How to get height for NSAttributedString at a fixed width

nsattributedstring get width swift
nsattributedstring boundingrect
calculate height string swift
calculate label width swift 4
get height of text in label swift
ios calculate text height
uitextview get line height
swift get label size for text

I want to do some drawing of NSAttributedStrings in fixed-width boxes, but am having trouble calculating the right height they'll take up when drawn. So far, I've tried:

  1. Calling - (NSSize) size, but the results are useless (for this purpose), as they'll give whatever width the string desires.

  2. Calling - (void)drawWithRect:(NSRect)rect options:(NSStringDrawingOptions)options with a rect shaped to the width I want and NSStringDrawingUsesLineFragmentOrigin in the options, exactly as I'm using in my drawing. The results are ... difficult to understand; certainly not what I'm looking for. (As is pointed out in a number of places, including this Cocoa-Dev thread).

  3. Creating a temporary NSTextView and doing: [[tmpView textStorage] setAttributedString:aString]; [tmpView setHorizontallyResizable:NO]; [tmpView sizeToFit]; When I query the frame of tmpView, the width is still as desired, and the height is often correct ... until I get to longer strings, when it's often half the size that's required. (There doesn't seem to be a max size being hit: one frame will be 273.0 high (about 300 too short), the other will be 478.0 (only 60-ish too short)).

I'd appreciate any pointers, if anyone else has managed this.

-[NSAttributedString boundingRectWithSize:options:]

You can specify NSStringDrawingUsesDeviceMetrics to get union of all glyph bounds.

Unlike -[NSAttributedString size], the returned NSRect represents the dimensions of the area that would change if the string is drawn.

As @Bryan comments, boundingRectWithSize:options: is deprecated (not recommended) in OS X 10.11 and later. This is because string styling is now dynamic depending on the context.

For OS X 10.11 and later, see Apple's Calculating Text Height developer documentation.

How to calculate the height of an NSAttributedString with given width , Option 2 does work in iOS with the proper parameters. NSAttributedString *attrStr = // your attributed string CGFloat width = 300; // whatever  The answer by @dezinezync answers half of the question. You'll just have to calculate the maximum size allowed for your UILabel with the given width and number of lines. First, get the height allowed based on number of lines: let maxHeight = font.lineHeight * numberOfLines Then calculate the bounding rect of the text you set based on the criteria:

The answer is to use - (void)drawWithRect:(NSRect)rect options:(NSStringDrawingOptions)options but the rect you pass in should have 0.0 in the dimension you want to be unlimited (which, er, makes perfect sense). Example here.

boundingRectWithSize:options:context:, The width and height constraints to apply when computing the string's bounding To calculate the bounding rectangle, this method uses the baseline origin by  There is a method for UItextView -sizeThatFits which returns the proper size for the text set. So instead of using boundingRectWithSize, create an UITextView, with a random frame, and call its sizeThatFits with the respective width and CGFLOAT_MAX height. It returns the size that will have the proper height.

You might be interested in Jerry Krinock's great (OS X only) NS(Attributed)String+Geometrics category, which is designed to do all sorts of string measurement, including what you're looking for.

size(), When setting the size of your view, use the ceil function to round fractional values up to the nearest whole number. See Also. Getting Metrics for the String. func  Swift's strings are great for storing plain text, but as soon as you want formatting, images, or interactivity you need to reach for NSAttributedString - Foundation’s all-in-one string handling class.

I have a complex attributed string with multiple fonts and got incorrect results with a few of the above answers that I tried first. Using a UITextView gave me the correct height, but was too slow for my use case (sizing collection cells). I wrote swift code using the same general approach described in the Apple doc referenced previously and described by Erik. This gave me correct results with must faster execution than having a UITextView do the calculation.

private func heightForString(_ str : NSAttributedString, width : CGFloat) -> CGFloat {
    let ts = NSTextStorage(attributedString: str)

    let size = CGSize(width:width, height:CGFloat.greatestFiniteMagnitude)

    let tc = NSTextContainer(size: size)
    tc.lineFragmentPadding = 0.0

    let lm = NSLayoutManager()
    lm.addTextContainer(tc)

    ts.addLayoutManager(lm)
    lm.glyphRange(forBoundingRect: CGRect(origin: .zero, size: size), in: tc)

    let rect = lm.usedRect(for: tc)

    return rect.integral.size.height
}

Helper for calculating String and NSAttributedString frame · GitHub, Download ZIP. Helper for calculating String and NSAttributedString frame fileprivate(set) var width: CGFloat = 0 return AZTextFrame(attributes: self).​height. @DannyC that will assign a new instance of NSAttributedString to the label and in practice doing that will lead to losing all the previous attributes it had. How I managed to do it: I looked at the source code for label renderer in iOS and figured out its actually of type NSMutableAttributedString so I first casted label.AttributedText to the

Use NSAttributedString method

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context

The size is the constraint on the area, the calculated area width is restricted to the specified width whereas the height is flexible based on this width. One can specify nil for context if that's not available. To get multi-line text size, use NSStringDrawingUsesLineFragmentOrigin for options.

How to identify number of lines for dynamic length label required for , For layout purposes, I want to know how to calculate the required height of an NSAttributedString under fixed width. I'm looking for something  To change the width of multiple columns, select the columns that you want to change, and then drag a boundary to the right of a selected column heading. To change the width of columns to fit the contents, select the column or columns that you want to change, and then double-click the boundary to the right of a selected column heading.

Getting text size on iOS - David, How to get height for NSAttributedString at a fixed width. I want to do some drawing of NSAttributedStrings in fixed-width boxes, but am having trouble calculating  CSS Setting height and width. The height and width properties are used to set the height and width of an element. The height and width properties do not include padding, borders, or margins. It sets the height/width of the area inside the padding, border, and margin of the element.

boundingRectWithSize for NSAttributedString returning wrong size , I also needed it in another place to get width with a defined height so I changed it to I'm not sure how fast it is but fixed the big issue I had. The aspect ratio of an element describes the proportional relationship between its width and its height. Two common video aspect ratios are 4:3 (the universal video format of the 20th century), and 16:9 (universal for HD television and European digital television). How To - Height Equal to Width. Step 1) Add HTML:

How to calculate height of a multiline String in Swift – Successful coder, For example – UITextView has textView.bounds.size.width – and this What I did to make the text work reliably was to not set the height at all  When calling .height(value), the value can be either a string (number and unit) or a number. If only a number is provided for the value, jQuery assumes a pixel unit. If a string is provided, however, a valid CSS measurement must be provided for the height (such as 100px, 50%, or auto ). Note that in modern browsers,

Comments
  • It seems that if you use NSStringDrawingUsesDeviceMetrics and there are no glyphs that this will return 0. Is there a way to handle both situations? Or must you some how know or keep track of whether you added a glyph? (Tested on iOS 8.)
  • It makes sense that a string with no visible content would return a zero sized rect. Are you seeing new behaviour on iOS 8 compared to iOS 7?
  • I meant that if you have an NSAttributedString with text (and no glyphs) and you use NSStringDrawingUsesDeviceMetrics the size is CGSizeZero. So it seems like you have to know if there are glyphs before you decide how to get the size...
  • Is it possible to have text without glyphs? Is this a common situation?
  • Bad news: this method is deprecated starting on OS 10.11 AND it no longer returns the correct height. It's too low. Works great on 10.10 and below, though.
  • This answer is outdated. Graham's answer below is the correct method as of 2014.
  • That code appears to be Mac specific. It won't help with iOS development.
  • You're right, the question was about NSTextView, which is a Mac class. I'm not even sure iOS had NSAttributedString when I answered this question.
  • Late input, but just a heads up: I've had problems with NS(Attributed)String+Geometrics consistently underestimating the height that long strings require. Until now, I've actually just fudged the result by adding an extra 25%. I'm now looking for a newer, better solution. I do not think NS(Attributed)String+Geometrics is working well on 10.9, 10.10 and 10.11.
  • Also: this assumes you've got an NSAttributedString created with a given font and the NSParagraphStyle you're looking for -- in my case, that's a left-aligned, word-wrapping, no-hyphenation paragraph style. Don't forget to create that when you create your attributedString.
  • This method is deprecated on 10.11+ and no longer works correctly; the returned height is too small on El Capitan.