在iOS 7中动态调整标签大小

4
在iOS 6中,我正在使用:
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);

动态调整UILabel的大小。这在iOS 7中不起作用,因此我尝试了以下方法:
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);

这是在UILabel类别内部,但这也不起作用...有什么想法我应该使用什么?


哪一部分出了问题?是计算的框架大小有误,还是标签大小没有改变? - tarmes
4个回答

6
尝试像这样做(不使用自动布局):
请尝试以下代码(不使用自动布局):
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;

3

如果没有更多关于为什么不起作用的详细信息,我猜测你需要使用选项NSStringDrawingUsesLineFragmentOrigin,以便它成为旧的sizeWithFont:的替代品,像这样:

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;

请注意文档中提到的内容:
在iOS 7及更高版本中,此方法返回分数大小(在返回的CGRect的大小组件中);要使用返回的大小来调整视图的大小,必须使用ceil函数将其值提高到最近的较高整数。
因此,要提取用于调整视图大小的计算高度或宽度,我会使用:
CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);

@user426132,请帮我理解哪里出了问题。sizeWithFont:的哪一部分没有像以前那样工作? - Mr. T

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

1

这个方法在iOS6和iOS7上应该可以使用,但是如果您需要恢复标签限制,则会破坏它们(您需要编程设置它们)。:

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

将此方法添加到您的视图控制器中,然后像这样使用它:
[self resizeHeightForLabel:myLabel];
//set new constraints here if needed

我需要调整宽度而不是高度...我会试一下..谢谢 - user426132
尝试一下,我认为修改代码以调整宽度并不难。 - Deniss Fedotovs
在调用此方法之前,请确保您已将标签添加到视图中(使用IB或以编程方式)。 如果您正在使用自动布局和约束,请尝试在应用此函数之前和之后记录标签框架的宽度/高度是否发生了变化。 如果框架已更改,则必须调整约束。 如果没有,则其他地方可能存在错误。 尝试类似于 NSLog(@“width:%f,height:%f”,myLabel.frame.size.width,mylabel.frame.size.height); 的东西来记录宽度/高度。 - Deniss Fedotovs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接