调整 CATextLayer 的大小以适应 iOS 上的文本 [英] Resize CATextLayer to fit text on iOS

查看:18
本文介绍了调整 CATextLayer 的大小以适应 iOS 上的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我的所有研究似乎都表明不可能准确地做到这一点.一开始我仅有的两个选择是:

All my research so far seems to indicate it is not possible to do this accurately. The only two options available to me at the outset were:

a) 为 CATextLayer 使用布局管理器 - 自 4.0 起在 iOS 上不可用

a) Using a Layout manager for the CATextLayer - not available on iOS as of 4.0

b) 使用 sizeWithFont:constrainedToSize:lineBreakMode: 并根据此处返回的大小调整 CATextLayer 的边框.

b) Use sizeWithFont:constrainedToSize:lineBreakMode: and adjust the frame of the CATextLayer according to the size returned here.

选项 (b) 是最简单的方法,应该可行.毕竟,它与 UILabel 完美配合.但是当我对 CATextLayer 应用相同的框架计算时,框架总是比预期或需要的大一点.

Option (b), being the simplest approach, should work. After all, it works perfectly with UILabels. But when I applied the same frame calculation to CATextLayer, the frame was always turning out to be a bit bigger than expected or needed.

事实证明,CATextLayers 和 UILabels 中的行间距(对于相同的字体和大小)是不同的.因此,sizeWithFont(其行距计算将与 UILabel 的行距计算匹配)不会返回 CATextLayers 的预期大小.

通过使用 UILabel 打印相同的文本,而不是 CATextLayer 并比较结果,进一步证明了这一点.第一行中的文本完全重叠(它是相同的字体),但 CATextLayer 中的行距仅比 UILabel 中的短一点.(对不起,我现在不能上传截图,因为我已经包含机密数据,而且我目前没有时间制作示例项目来获得干净的截图.我会稍后上传它们以供后人使用,当我有时间)

This is further proven by printing the same text using a UILabel, as against a CATextLayer and comparing the results. The text in the first line overlaps perfectly (it being the same font), but the line-spacing in CATextLayer is just a little shorter than in UILabel. (Sorry I can't upload a screenshot right now as the ones I already have contain confidential data, and I presently don't have the time to make a sample project to get clean screenshots. I'll upload them later for posterity, when I have the time)

这是一个奇怪的区别,但我认为可以通过为我在那里使用的 NSAttributedString 指定适当的属性来调整 CATextLayer 中的间距,但似乎并非如此.查看 CFStringAttributes.h 我找不到可能与行距相关的单个属性.

This is a weird difference, but I thought it would be possible to adjust the spacing in the CATextLayer by specifying the appropriate attribute for the NSAttributedString I use there, but that does not seem to be the case. Looking into CFStringAttributes.h I can't find a single attribute that could be related to line-spacing.

底线:

因此,在需要图层适合其文本的情况下,似乎无法在 iOS 上使用 CATextLayer.我是对的还是我错过了什么?

So it seems like it's not possible to use CATextLayer on iOS in a scenario where the layer is required to fit to its text. Am I right on this or am I missing something?

附注:

  1. 我想使用 CATextLayer 和 NSAttributedString's 的原因是因为要显示的字符串在不同的点上会有不同的颜色.我想我只需要像往常一样重新手动绘制字符串......当然,总是可以选择从 sizeWithFont 获取结果以获得正确的行高.

  1. The reason I wanted to use CATextLayer and NSAttributedString's is because the string to be displayed is to be colored differently at different points. I guess I'd just have to go back to drawing the strings by hand as always....of course there's always the option of hacking the results from sizeWithFont to get the proper line-height.

稍微滥用代码"标签以使帖子更具可读性.

Abusing the 'code' tags a little to make the post more readable.

我无法用CATextLayer"标记帖子 - 令人惊讶的是,目前不存在此类标记.如果有足够声誉的人碰到这篇文章,请相应地标记它.

I'm not able to tag the post with 'CATextLayer' - surprisingly no such tags exist at the moment. If someone with enough reputation bumps into this post, please tag it accordingly.

推荐答案

试试这个:

- (CGFloat)boundingHeightForWidth:(CGFloat)inWidth withAttributedString:(NSAttributedString *)attributedString {
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString( (CFMutableAttributedStringRef) attributedString); 
    CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(inWidth, CGFLOAT_MAX), NULL);
    CFRelease(framesetter);
    return suggestedSize.height;
}

您必须将 NSString 转换为 NSAttributedString.在 CATextLayer 的情况下,您可以使用以下 CATextLayer 子类方法:

You'll have to convert your NSString to NSAttributedString. In-case of CATextLayer, you can use following CATextLayer subclass method:

- (NSAttributedString *)attributedString {

    // If string is an attributed string
    if ([self.string isKindOfClass:[NSAttributedString class]]) {
        return self.string;
    }

    // Collect required parameters, and construct an attributed string
    NSString *string = self.string;
    CGColorRef color = self.foregroundColor;
    CTFontRef theFont = self.font;
    CTTextAlignment alignment;

    if ([self.alignmentMode isEqualToString:kCAAlignmentLeft]) {
        alignment = kCTLeftTextAlignment;

    } else if ([self.alignmentMode isEqualToString:kCAAlignmentRight]) {
        alignment = kCTRightTextAlignment;

    } else if ([self.alignmentMode isEqualToString:kCAAlignmentCenter]) {
        alignment = kCTCenterTextAlignment;

    } else if ([self.alignmentMode isEqualToString:kCAAlignmentJustified]) {
        alignment = kCTJustifiedTextAlignment;

    } else if ([self.alignmentMode isEqualToString:kCAAlignmentNatural]) {
        alignment = kCTNaturalTextAlignment;
    }

    // Process the information to get an attributed string
    CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);

    if (string != nil)
        CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)string);

    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTForegroundColorAttributeName, color);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTFontAttributeName, theFont);

    CTParagraphStyleSetting settings[] = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTParagraphStyleAttributeName, paragraphStyle);    
    CFRelease(paragraphStyle);

    NSMutableAttributedString *ret = (NSMutableAttributedString *)attrString;

    return [ret autorelease];
}

HTH.

这篇关于调整 CATextLayer 的大小以适应 iOS 上的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆