Dynamically resize label in iOS 7

后端 未结 4 1929
旧巷少年郎
旧巷少年郎 2020-12-09 14:19

In iOS 6, I am using :

CGSize labelSize = [self.text sizeWithFont:self.font constrainedToSize:size lineBreakMode:self.lineBreakMode];
self.frame = CGRectMake         


        
相关标签:
4条回答
  • 2020-12-09 14:24

    Try something like this (working without auto-layout) :

    NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                                               [UIFont fontWithName:@"FontName" size:15], NSFontAttributeName,
                                                                nil];
    
    CGRect frame = [label.text boundingRectWithSize:CGSizeMake(263, 2000.0)
                                                         options:NSStringDrawingUsesLineFragmentOrigin
                                                      attributes:attributesDictionary
                                                         context:nil];
    
    CGSize size = frame.size;
    
    0 讨论(0)
  • 2020-12-09 14:24

    This should work in iOS6 and iOS7, but will break your label constraints (you need to set them all back programatically if needed):

    -(void)resizeHeightForLabel: (UILabel*)label {
        label.numberOfLines = 0;
        UIView *superview = label.superview;
        [label removeFromSuperview];
        [label removeConstraints:label.constraints];
        CGRect labelFrame = label.frame;
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
            CGRect expectedFrame = [label.text boundingRectWithSize:CGSizeMake(label.frame.size.width, 9999)
                                                            options:NSStringDrawingUsesLineFragmentOrigin
                                                         attributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                                     label.font, NSFontAttributeName,
                                                                     nil]
                                                            context:nil];
            labelFrame.size = expectedFrame.size;
            labelFrame.size.height = ceil(labelFrame.size.height); //iOS7 is not rounding up to the nearest whole number
        } else {
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
            labelFrame.size = [label.text sizeWithFont:label.font
                                     constrainedToSize:CGSizeMake(label.frame.size.width, 9999)
                                         lineBreakMode:label.lineBreakMode];
    #pragma GCC diagnostic warning "-Wdeprecated-declarations"
        }
        label.frame = labelFrame;
        [superview addSubview:label];
    }
    

    Add this method to your viewController and use it like this:

    [self resizeHeightForLabel:myLabel];
    //set new constraints here if needed
    
    0 讨论(0)
  • 2020-12-09 14:26

    Without more details on why it doesn't work, my guess would be that you need to use the option NSStringDrawingUsesLineFragmentOrigin in order for it to become a drop-in replacement for the old sizeWithFont:, like this:

    NSString *text = ...;
    CGFloat width = ...;
    UIFont *font = ...;
    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:text
            attributes:@
            {
                NSFontAttributeName: font
            }];
    CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    CGSize size = rect.size;
    

    Please note the documentation mentions:

    In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

    So to pull out the calculated height or width to be used for sizing views, I would use:

    CGFloat height = ceilf(size.height);
    CGFloat width  = ceilf(size.width);
    
    0 讨论(0)
  • 2020-12-09 14:35
    - (void)resizeLabelByContent:(UILabel *)label
    {
    
        CGSize maxSize = CGSizeMake(label.width, 999);
    
        NSString *contentStr = label.text;
    
        UIFont *contentFont = label.font;
    
        CGRect contentFrame;
    
        NSString *version = [[UIDevice currentDevice] systemVersion];
    
        if ([version floatValue] < 7.0) {
    
            CGSize contentStringSize = [contentStr sizeWithFont:contentFont constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
    
            contentFrame = CGRectMake(label.left, label.top, label.width, contentStringSize.height);
    
        } else {
    
            NSDictionary *contentDic = [NSDictionary dictionaryWithObjectsAndKeys:contentFont, NSFontAttributeName, nil];
    
            CGSize contentStrSize = [contentStr boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:contentDic context:nil].size;
    
            contentFrame = CGRectMake(label.left, label.top, label.width, contentStrSize.height);
        }
    
        label.frame = contentFrame;
    }
    
    0 讨论(0)
提交回复
热议问题