How to get the width of an NSString?

2019-01-08 13:58发布

问题:

I am trying to get the width of an NSString (ex. NSString *myString = @"hello"). Is there a way to do this?

Thanks.

回答1:

Here's a relatively simple approach. Just create an NSAttributedString with the appropriate font and ask for its size:

- (CGFloat)widthOfString:(NSString *)string withFont:(NSFont *)font {
     NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
     return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].width;
 }


回答2:

UIFont * font = [UIFont systemFontOfSize:15];

CGSize stringSize = [aString sizeWithFont:font]; 

CGFloat width = stringSize.width;


回答3:

Send the string a sizeWithAttributes: message, passing a dictionary containing the attributes with which you want to measure the string.



回答4:

i dont know if you are suppose to use this in cocoa touch. if it is, then:

- (CGFloat)widthOfString:(NSString *)string withFont:(NSFont *)font {
     NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
     return [[[NSAttributedString alloc] initWithString:string attributes:attributes] size].width;
 }

wont work.

in cocoa touch, you gotta add coretext framework and import the header and write your code like this:

UIFont *font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:DEFAULT_FONT_SIZE];
//    NSLog(@"%@", NSFontAttributeName);
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, (NSString     *)kCTFontAttributeName, nil];

but, GEE!!!!!

NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithString:self.caption attributes:attributes];
[as size].width;

there's no size this method in NSMutableAttributedString!

finally, this would work

[self.caption sizeWithFont:font].width


回答5:

as for ios 7 and up this is the correct way:

NSString * buttonTitle = @"demo title";
CGSize stringSize = [buttonTitle sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];


回答6:

Using the UILabel's attributed string:

- (CGSize)getStringSizeWithText:(NSString *)string font:(UIFont *)font{

    UILabel *label = [[UILabel alloc] init];
    label.text = string;
    label.font = font;

    return label.attributedText.size;
}


回答7:

Sorry my question was not detailed enough and is not exactly what I'm trying to do. I am using a text storage, layout manager and a text container. The solution is to use the layout manager to determine the rectangle that bounds the rect. Here is the code.

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"hello"];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] init];

[layoutManager addTextContainer:textContainer];
[textContainer release];

[textStorage addLayoutManager:layoutManager];
[layoutManager release];

//Figure out the bounding rectangle
NSRect stringRect = [layoutManager boundingRectForGlyphRange:NSMakeRange(0, [layoutManager numberOfGlyphs]) inTextContainer:textContainer];


回答8:

UIKit has a nice addition to NSString, making sizeWithAttributes: a bit lighter:

CGSize titleSize = [title sizeWithFont:titleFont 
                     constrainedToSize:contentCellSize 
                         lineBreakMode:UILineBreakModeWordWrap];


回答9:

Here's Stephen's solution in Clozure Common Lisp, when using the Objective C bridge. I came across this post when searching for a solution, and I just rewrote Stephen's version which worked fine for me. Others using Clozure might find this helpful:

(defun string-width (str font)
  (let* ((dict (#/dictionaryWithObjectsAndKeys: ns:ns-mutable-dictionary
                font #$NSFontAttributeName
                ccl:+null-ptr+))
         (attr (#/initWithString:attributes: (#/alloc ns:ns-attributed-string)
                (ccl::%make-nsstring str)
                dict))
         (size (#/size attr)))
    (ns:ns-size-width size)))


回答10:

Just in case you are wondering how to check a label size, you should use the UIFont, instead of the NSFont (not even sure if exists)