UIKit's [NSString sizeWithFont:constrainedToSize:] in AppKit

前端 未结 6 1235
旧巷少年郎
旧巷少年郎 2021-01-02 22:47

Is there any equivalent method in AppKit (for Cocoa on Mac OS X) that does the same thing as UIKit\'s [NSString sizeWithFont:constrainedToSize:]?

If not

相关标签:
6条回答
  • 2021-01-02 22:51

    If you want to constrain the string to a certain size, you use -[NSString boundingRectWithSize:options:attributes:]. The .size of the returned NSRect is the size you're looking for.

    0 讨论(0)
  • 2021-01-02 22:56

    Try this one:

    bounds = [value boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes];
    
    0 讨论(0)
  • 2021-01-02 22:56

    The newer NSExtendedStringDrawing category API (methods with the NSStringDrawingOptions argument) behaves in the single line mode. If you want to measure/render in multi line mode, want to specify NSStringDrawingUsesLineFragmentOrigin.

    0 讨论(0)
  • 2021-01-02 22:57

    Here is a more complete example of how you can do this using boundingRectWithSize.

    // get the text field
    NSTextField* field = (NSTextField*)view;
    
    // create the new font for the text field
    NSFont* newFont = [NSFont fontWithName:@"Trebuchet MS" size:11.0];
    
    // set the font on the text field
    [field setFont:newFont];
    
    // calculate the size the textfield needs to be in order to display the text properly
    NSString* text      = field.stringValue;
    NSInteger maxWidth  = field.frame.size.width;
    NSInteger maxHeight = 20000;
    CGSize constraint   = CGSizeMake(maxWidth, maxHeight);
    NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:NSFontAttributeName,newFont, nil];
    NSRect newBounds    = [text boundingRectWithSize:constraint
                                             options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attrs];
    
    // set the size of the text field to the calculated size
    field.frame = NSMakeRect(field.frame.origin.x, field.frame.origin.y, field.frame.size.width, newBounds.size.height);
    

    Of course, for additional info, take a look at the Apple documentation:

    • Options for the attributes dictionary
    • boundingRectWithSize
    0 讨论(0)
  • 2021-01-02 23:09

    EDIT: You should be able to do things the normal way in Lion and later. The problems described below have been fixed.


    There is no way to accurately measure text among the current Mac OS X APIs.

    There are several APIs that promise to work but don't. That's one of them; Core Text's function for this purpose is another. Some methods return results that are close but wrong; some return results that seem to mean nothing at all. I haven't filed any bugs on these yet, but when I do, I'll edit the Radar numbers into this answer. You should file a bug as well, and include your code in a small sample project.

    [Apparently I have already filed the Core Text one: 8666756. It's closed as a duplicate of an unspecified other bug. For Cocoa, I filed 9022238 about the method Dave suggested, and will file two NSLayoutManager bugs tomorrow.]

    This is the closest solution I've found.

    0 讨论(0)
  • 2021-01-02 23:14

    If you search the documentation for NSString, you will find the "NSString Application Kit Additions Reference", which is pretty much analogous to the UIKit counterpart.

    -[NSString sizeWithAttributes:]
    

    is the method you are looking for.

    0 讨论(0)
提交回复
热议问题