在 Objective-C 中计算具有不同语言和表情符号的文本的 UILabel 高度
Posted
技术标签:
【中文标题】在 Objective-C 中计算具有不同语言和表情符号的文本的 UILabel 高度【英文标题】:Calculate UILabel height for text with different languages and emojis in Objective-C 【发布时间】: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,我完全没有问题,而且我认为它不会对您产生太大影响...
【参考方案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);
【讨论】:
以上是关于在 Objective-C 中计算具有不同语言和表情符号的文本的 UILabel 高度的主要内容,如果未能解决你的问题,请参考以下文章
iOS和watchOS(Objective-C)具有不同方法的相同类对象