如何使用 space 行准确获取 UILabel 的高度?

How to get exactly height of UILabel with line space?

我正在编写一个可扩展的 tableView header,我需要在 tableView 委托方法中准确设置 header 的高度。我现在使用以下方法计算我的 header(multi-line 标签的高度):

CGRect calcuRect = [headerText boundingRectWithSize:CGSizeMake(myLabelWitdh, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:myLabelFont} context:nil];
CGFloat headerHeight = calcuRect.size.height;

但是,我发现计算出的高度只是没有包含行 space 的文本。 那么如何获取标签的行space高度呢?或者如何使用 space?

行获取 UILabel 的准确高度

您需要调整标签框的大小。尝试:[label sizeToFit];

同样使用以下方法。

- (CGFloat)heightForWidth:(CGFloat)width usingFont:(UIFont *)font withText:(NSString *)aStrText
{
    CGSize labelSize = (CGSize){width, FLT_MAX};
    CGRect rect = [aStrText boundingRectWithSize:labelSize
                                         options:NSStringDrawingUsesLineFragmentOrigin
                                      attributes:@{NSFontAttributeName : font}
                                         context:nil];
    return rect.size.height;
}
    override func viewDidLayoutSubviews() {
          super.viewDidLayoutSubviews()
          sizeToFit()

        }
       func sizeToFit(){
            let header = customHeaderView
            let height = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height;
            var headerFrame = header.frame

            headerFrame.size.height = height
            header.frame = headerFrame
            tableView.tableHeaderView = header;



    }
Hope this will help you. 

您可以通过完全传递相同的字体大小和类型并进行一些计算来获得 UILabel 的确切高度。
这里我使用了 Helvetica 字体的 UILabel,字体大小为 16。

Objective C

- (CGFloat)requiredHeight:(NSString*)labelText{

    UIFont *font = [UIFont fontWithName:@"Helvetica" size:16.0];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, CGFLOAT_MAX)];
    label.numberOfLines = 0;
    label.lineBreakMode = NSLineBreakByWordWrapping;
    label.font = font;
    label.text = labelText;
    [label sizeToFit];
    return label.frame.size.height;

}

输出

CGFloat size = [self requiredHeight:@"iOS Rocks"];
NSLog(@"%f",size);

size = [self requiredHeight:@"iOS Rocks\n"];
NSLog(@"%f",size);

控制台输出

2016-04-10 01:37:46.812 testPro[6093:327503] 18.500000
2016-04-10 01:37:46.814 testPro[6093:327503] 37.000000

Swift 2.2

func requiredHeight(labelText:String) -> CGFloat {

    let font = UIFont(name: "Helvetica", size: 16.0)
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, 200, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = labelText
    label.sizeToFit()
    return label.frame.height

}

编辑
Swift 3.0

func requiredHeight(labelText:String) -> CGFloat {

    let font = UIFont(name: "Helvetica", size: 16.0)
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: .max))
    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.font = font
    label.text = labelText
    label.sizeToFit()
    return label.frame.height

}

事实上,我想在我的 table 视图中创建一个可扩展部分 header,但是在委托方法中:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

这个方法必须return我标签的准确高度header,我用下面的方法来计算高度,但是高度不包括行space,只有文字身高;

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary<NSString *, id> *)attributes context:(NSStringDrawingContext *)context;

由于对sizeToFit了解较多,这里给出一个可行的答案

- (void)viewDidLoad {
    [super viewDidLoad];

    [self tableViewInit];
    [self headerInit];
}

- (void)tableViewInit {
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:_tableView];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
}

- (void)headerInit {
    CGRect originSize = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, CGFLOAT_MIN);
    self.header = [[UILabel alloc] initWithFrame:originSize];
    self.header.lineBreakMode = NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail;
    self.header.text = self.headerStr;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (self.showAll) {
        self.header.numberOfLines = 0;
        [self.header sizeToFit];
    } else {
        self.header.numberOfLines = 2;
        [self.header sizeToFit];
    }
    return self.header.bounds.size.height;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return self.header;
}

根据 Rajan Maheshwari 的回答,我在 Swift 3.0 中为具有可选行高的通用标签编写了此函数。希望对你有帮助。

func heightForLabel(_ text: String, font: UIFont, width: CGFloat, lineSpacing: CGFloat) -> CGFloat {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    if lineSpacing > 0.0 {
        let style = NSMutableParagraphStyle()
        style.lineSpacing = lineSpacing
        style.alignment = .center
        label.attributedText = NSAttributedString(string: text, attributes: [NSParagraphStyleAttributeName: style])
    } else {
        label.text = text
    }
    label.sizeToFit()
    return label.frame.height
}