【问题标题】:How to get exactly height of UILabel with line space?如何使用行距获得 UILabel 的准确高度?
【发布时间】:2016-04-09 04:07:29
【问题描述】:

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

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

但是,我发现计算出的高度只是关于没有包含行空间的文本。 那么如何获得标签的行距高度呢?或者如何通过行距获得 UILabel 的准确高度?

【问题讨论】:

  • 有人了解我吗?如何获取值 = wordsTotalHeight+(lineNum-1)*lineSpace。这个方法返回wordsTotalHeight,但是如何获取lineSpace的值呢?

标签: ios objective-c uilabel


【解决方案1】:

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

目标 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

斯威夫特 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

}

【讨论】:

    【解决方案2】:

    根据 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
    }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 不是sizeToFit,我只是想知道多标签的确切高度
      【解决方案4】:

      同样使用以下方法。

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

      【讨论】:

      • 问题是,这个方法只返回文字的高度,不包括行距,如果标签有多行,这个高度会小于实际高度。
      【解决方案5】:
          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. 
      

      【讨论】:

        【解决方案6】:

        事实上,我想在我的表格视图中创建一个可扩展的节标题,但是在委托方法中:

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

        此方法必须返回我的标签标题的确切高度,我使用以下方法计算高度,但是高度不包括行距,而只有文字高度;

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

        【讨论】:

          猜你喜欢
          • 2012-03-10
          • 2013-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多