Dynamically resize label in iOS 7

蓝咒 提交于 2019-12-28 13:40:24

问题


In iOS 6, I am using :

CGSize labelSize = [self.text sizeWithFont:self.font constrainedToSize:size lineBreakMode:self.lineBreakMode];
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y , labelSize.width, self.frame.size.height);

To dynamically resize a UILabel. This does not work in iOS 7 so I tried:

NSString *text = self.text;
CGFloat width = size.width;
UIFont *font = self.font;
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text
                                                                 attributes:@{ NSFontAttributeName: font }];

CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
                              options:NSStringDrawingUsesDeviceMetrics
                              context:nil];
CGSize size = rect.size;

self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y , size.width, self.frame.size.height);

This is inside a category on UILabel, but this is not working also... Any ideas what I should be using?


回答1:


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;



回答2:


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);



回答3:


- (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;
}



回答4:


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


来源:https://stackoverflow.com/questions/19029018/dynamically-resize-label-in-ios-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!