【问题标题】:boundingRectWithSize : Incorrect calculation of UILabel Height when multiple newlines are presentboundingRectWithSize :当存在多个换行符时,UILabel 高度的计算不正确
【发布时间】:2020-12-16 09:30:01
【问题描述】:

我正在尝试以编程方式计算标签的高度。

我的示例文本如下所示:

Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。 Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur。

Excepteur sint occaecat cupidatat non proident, sint in culpa qui officia deserunt mollit anim id est laborum。

我用来计算标签高度的代码:

-(CGFloat)getLabelHeightUsingWidth:(CGFloat)cellWidth
{
  NSInteger fontSize      = 16;
  UIFont *descLabelFont   = [UIFont fontWithName:@"MyFontName" size:fontSize];
  NSString *description   = <sample text provided above>;
  CGSize constraint = CGSizeMake(width, CGFLOAT_MAX);
  CGSize size;
  NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
  CGSize boundingBox = [text boundingRectWithSize:constraint    options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font}
                                            context:context].size;
  size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
    
  return size.height ;
}

对于包含单个换行符或没有换行符的文本内容,它会给出适当的高度,但不会像我的示例文本中那样使用双换行符。当存在双换行符时,返回的计算高度小于实际需要的高度。因此,返回的高度会更小,显示时的原始高度会更多地为我在其中显示多行字符串的表格单元格创建不正确的高度问题。

因此,我推断双换行符可能是问题所在,并尝试使用单个换行符删除双换行符。那么,计算的高度是正确的。

处理这种情况的正确方法是什么?

【问题讨论】:

    标签: ios objective-c uilabel


    【解决方案1】:

    很难确切地说出了什么问题...也许您(不小心)没有使用相同的字体?也许(不小心)没有使用完全相同的字符串?

    无论如何,这似乎有点奇怪。

    试试这个:

    LabelHeightViewController.h

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface LabelHeightViewController : UIViewController
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    LabelHeightViewController.m

    #import "LabelHeightViewController.h"
    
    @interface LabelHeightViewController ()
    
    @property (strong, nonatomic) UILabel *myLabel;
    @property (strong, nonatomic) UIView *redView;
    
    @end
    
    @implementation LabelHeightViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        _myLabel = [UILabel new];
        _redView = [UIView new];
        
        _myLabel.translatesAutoresizingMaskIntoConstraints = NO;
        _redView.translatesAutoresizingMaskIntoConstraints = NO;
        
        _myLabel.numberOfLines = 0;
        _myLabel.text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n\n\nExcepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
        
        UIFont *font = [UIFont fontWithName:@"Avenir-Book" size:16.0];
        _myLabel.font = font;
        
        // we're going to set the label width to 300
        CGFloat w = 300.0;
    
        // calculate the height
        CGFloat h = [self getLabelHeight:_myLabel forWidth:w];
        
        [self.view addSubview:_myLabel];
        [self.view addSubview:_redView];
        
        UILayoutGuide *g = self.view.layoutMarginsGuide;
        
        [NSLayoutConstraint activateConstraints:@[
            
            // constrain label Top: 40 / Leading: 12 / Width: w
            [_myLabel.topAnchor constraintEqualToAnchor:g.topAnchor constant:40.0],
            [_myLabel.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:12.0],
            [_myLabel.widthAnchor constraintEqualToConstant:w],
            
            // constrain red view Top: label Top / Leading: label leading + 8
            //  Width: 20 / Height: h
            [_redView.topAnchor constraintEqualToAnchor:_myLabel.topAnchor],
            [_redView.leadingAnchor constraintEqualToAnchor:_myLabel.trailingAnchor constant:8.0],
            [_redView.widthAnchor constraintEqualToConstant:20.0],
            [_redView.heightAnchor constraintEqualToConstant:h],
            
        ]];
        
        // so we can see the frames
        _myLabel.backgroundColor = [UIColor yellowColor];
        _redView.backgroundColor = [UIColor redColor];
        
    }
    
    -(CGFloat)getLabelHeight:(UILabel *)theLabel forWidth:(CGFloat)theWidth {
        UIFont *descLabelFont   = theLabel.font;
        NSString *description   = theLabel.text;
        CGSize constraint = CGSizeMake(theWidth, CGFLOAT_MAX);
        NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
        CGSize boundingBox = [description boundingRectWithSize:constraint
                                                       options:NSStringDrawingUsesLineFragmentOrigin
                                                    attributes:@{NSFontAttributeName:descLabelFont}
                                                       context:context].size;
        return ceil(boundingBox.height);
    }
    
    @end
    

    结果:

    注意事项:

    红色视图的高度设置为返回的高度

    -(CGFloat)getLabelHeight:(UILabel *)theLabel forWidth:(CGFloat)theWidth`
    

    文本有两个换行符 - \n\n - 用于第一个“中断”和 3 个换行符 - \n\n\n - 用于第二个中断(用于演示)。

    【讨论】:

      【解决方案2】:

      我在垂直 UIStackView 中的 UIView 中的 UILabel 上也看到了这种情况。 当文本中有 2 个 \n\n 时,它不会正确调整它的大小,它会丢失 1 行。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      相关资源
      最近更新 更多