【问题标题】:Calculate UILabel height for text with different languages and emojis in Objective-C在 Objective-C 中计算具有不同语言和表情符号的文本的 UILabel 高度
【发布时间】:2016-03-27 13:57:34
【问题描述】:

我需要计算可能是英文/表情符号/其他语言的给定文本的帧大小。

我的做法是:

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:fontSize], NSParagraphStyleAttributeName: style};
CGSize rect = [text boundingRectWithSize:CGSizeMake(containerWidth, CGFLOAT_MAX)
                               options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                            attributes:attributes
                               context:nil].size;

只要我不使用表情符号,它就可以正常工作。表情符号行高/字体大小似乎与常规字体不同。

我看到人们尝试以不同的方式解决它,例如: http://youbbe.xyz/issue/4987325/ios-emoji-messed-up-in-uilabel

此解决方案适用于表情符号,但不适用于英文/其他字体。

查看示例图片:

如您所见,仅文本计算良好(第一个框),但文本+表情符号计算不正确(第二个框)。

我真的很惊讶这个问题没有简单的解决方案。 非常感谢您的帮助。

【问题讨论】:

  • 尝试使用以下函数,但您必须使用发送属性文本和 TextVew 的宽度,并且函数返回 textview 的高度 - (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width { UITextView *textView = [[UITextView alloc] init]; [textView setAttributedText:text]; CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)]; //textView.textContainerInset = UIEdgeInsetsZero; return size.height+10; }
  • 看看这个..article
  • 什么是containerWidth?你在哪里设置?实际设置标签框架的代码是什么样的?
  • 你试过 UITextView 和 sizeToFit() 吗?
  • 尝试使用 textView,我完全没有问题,而且我认为它不会对您产生太大影响...

标签: ios objective-c uilabel emoji


【解决方案1】:

使用 UILabel 你可以简单地说:

CGSize size = [label sizeThatFits:CGSizeMake(containerWidth, CGFLOAT_MAX)];

你试过吗?我不认为表情符号有不同的行高,而是它们通常占据整个行高。

您可以只说[label sizeToFit];,然后从框架中获取大小(例如CGSize size = label.frame.size;)。这似乎是为不同字体大小获取正确大小的最一致准确的方法。

您可以将一些代码here 复制并粘贴到 Playground 中,然后查看不同的结果。

【讨论】:

  • 我试过了,但它不起作用...我看到很多人的回答方式相同,但没有一个真正有效...
  • 你应该展示你得到了什么以及你期待什么。
  • 如果您不明白问题所在 - 不要打扰回复。正如我不止一次告诉你的那样,你可以阅读主题并查看示例 - sizeToFit 不起作用。
  • 您应该在问题中包含您已经尝试过的内容,以节省时间和挫败感。此外,简单地说“它不起作用”既没有帮助也没有建设性。我提供了在特定条件下工作的代码。您应该更具体地了解它不起作用的条件。例如,iOS 的目标是什么版本?您的视图层次结构的其余部分是什么样的?你用的是什么字符串?从不起作用的代码中得到什么值?你在使用自动布局吗?所有这些事情都可能与您的问题有关。
  • 正如我之前所说的 - 我尝试了此处提供的所有示例。我提供了图像,并提供了确切问题的示例。使用表情符号时 - 高度计算不正确。我没有使用自动布局。我只有一个 UILable。我没有针对任何特定的 ios 版本。
【解决方案2】:

一种可能的解决方案是使用属性字符串设置文本并指定段落样式

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 5;
paragraphStyle.lineHeightMultiple = 1.1;
paragraphStyle.maximumLineHeight = 16;

maximumLineHeight 可以限制包含表情符号的行的高度。

【讨论】:

    【解决方案3】:

    将字符串转换为NSAttributedString,然后使用这个类别:

    - (CGFloat)heightForAttributedStringWithEmojisForWidth:(CGFloat)width {
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self);
        CFRange fitRange;
        CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [self length]), NULL, CGSizeMake(width, CGFLOAT_MAX), &fitRange);
        CFRelease(framesetter);
        return ceilf(frameSize.height);
    }
    

    【讨论】:

      【解决方案4】:
      //may be it will help for you
          NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
          //set the line break mode
          paragraphStyle.lineBreakMode = yourLabel.lineBreakMode;
      
          NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:yourLabel.font,
                                    NSFontAttributeName,
                                    paragraphStyle,
                                    NSParagraphStyleAttributeName,
                                    nil];
      
      
          CGRect rect = [yourLabel.text boundingRectWithSize:CGSizeMake(yourLabel.frame.size.width, yourLabel)
                                                        options:NSStringDrawingUsesLineFragmentOrigin
                                                     attributes:attrDict
                                                        context:nil];
          CGSize size = rect.size;
      

      【讨论】:

      • 正如其他人在这里回答的那样。此解决方案不起作用。
      【解决方案5】:
      + (CGFloat)heightForText:(NSString *)text {
      
          CGFloat offset = 5.f;
      
          UIFont *font = [UIFont systemFontOfSize:textHeight];
          NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
          paragraph.lineBreakMode = NSLineBreakByWordWrapping;
          paragraph.alignment = NSTextAlignmentCenter;
          NSDictionary *attributes = [[NSDictionary alloc] initWithObjectsAndKeys:
                                  font, NSFontAttributeName,
                                  paragraph, NSParagraphStyleAttributeName, nil];
      
          //size of one field
          CGSize textSize = [text sizeWithAttributes:attributes];
      
          CGRect textRect = [text boundingRectWithSize:CGSizeMake(320.f - offset * 2.f, CGFLOAT_MAX)
                                           options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                        attributes:attributes
                                           context:nil];
      
          return CGRectGetHeight(textRect);
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-14
        • 2017-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-11
        相关资源
        最近更新 更多