sizeWithFont method is deprecated. boundingRectWithSize returns an unexpected value

前端 未结 6 1374
傲寒
傲寒 2020-12-02 06:38

In iOS7, sizeWithFont is deprecated, so I am using boundingRectWithSize(which returns a CGRect value). My code:

 UIFont *fontText =         


        
6条回答
  •  青春惊慌失措
    2020-12-02 07:18

    Here is my working code snippet:

    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];
    
    NSString *headline  = [dict objectForKey:@"title"];  
    UIFont *font        = [UIFont boldSystemFontOfSize:18];  
    CGRect  rect        = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    
    CGFloat height      = roundf(rect.size.height +4)
    

    I added 4px to the calculated height, because without these 4px, there is one line missing.

    I use this code snippet in a tableView and add the "height" to an array of NSNumbers and I get the correct cell height for the default textLabel.

    Add 4 more pixel if you want more space under the text in the textLabel.

    **** UPDATE ****

    I do not agree with the "width bug of 40px", I shout be the 4px of missing height, because 4px is the default height of a space between a letter and the bound of a single line. You can check it with a UILabel, for a fontsize of 16 you need a UILabel height of 20.

    But if your last line has no "g" or whatever in it, the measuring could be miss the 4px of height.

    I rechecked it with a little method, I get an accurate height of 20,40 or 60 for my label and a right width less than 300px.

    To support iOS6 and iOS7, you can use my method:

    - (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
    {
        CGRect rect;
    
        float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
        if (iosVersion >= 7.0) {
            rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
        }
        else {
            CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
            rect = CGRectMake(0, 0, size.width, size.height);
        }
        NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
        return rect.size.height;
    }
    

    **** UPGRADE ****

    Thanks to your comments, I upgraded my function as followed. Since sizeWithFont is deprecated and you will get a warning in XCode, I added the diagnostic-pragma-code to remove the warning for this particular function-call/block of code.

    - (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
    {
        CGRect rect;
    
        if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
            rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
        }
        else {
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
            CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
            rect = CGRectMake(0, 0, size.width, size.height);
    #pragma GCC diagnostic pop
        }
        return ceil(rect.size.height);
    }
    

    In addition to the 4px topic: depending which font and font-weight you use, the calculation returns different height-values. In my case: HelveticaNeue-Medium with a fontsize of 16.0 returns a line-height of 20.0 for a single line but 39.0 for two lines, 78px for 4 lines --> 1px missing for every line - beginning with line 2 - but you want to have your fontsize + 4px linespace for every line you have to get a height-result.
    Please keep that in mind while coding!
    I don´t have a function yet for this "problem" but I will update this post when I´m finished.

提交回复
热议问题