NSAttributedString报告UITextView sizeThatFits和boundingRectWithSize的大小不正确,并设置了正确的选项 [英] NSAttributedString reporting incorrect sizes for UITextView sizeThatFits and boundingRectWithSize with correct options set

查看:1506
本文介绍了NSAttributedString报告UITextView sizeThatFits和boundingRectWithSize的大小不正确,并设置了正确的选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个NSAttributedString报告一个boundingRectWithSize(并且扩展名为UITextView,它不正确地计算它的sizeThatFits)当字体大小从用于创建它的字体大小减少时。

I have an NSAttributedString that is reporting a boundingRectWithSize (and by extension a UITextView which improperly calculates its sizeThatFits) when the font size is decreased from the font size that was used to create it.

在我执行类似操作的所有NSAttributedStrings上都没有发生,所以这里是重现的步骤。

It doesn't happen on all NSAttributedStrings for which I do similar operations, so here's the steps to reproduce.


  1. 使用不包含完整unicode字符集的非标准字体。

  2. 确保字符串包含此不支持集中的字符。 iOS会将它们渲染为适当大小的Helvetica。

  3. 在NSAttributedString中的所有字体属性上缩放字体。我生成问题的代码看起来像这样。

来自UITextView子类:

From inside a UITextView subclass:

NSMutableAttributedString *mutableString = [self.attributedText mutableCopy];
[mutableString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, mutableString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
    if (value) {
        UIFont *oldFont = (UIFont *)value;
        UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize - 1];
        [mutableString removeAttribute:NSFontAttributeName range:range];
        [mutableString addAttribute:NSFontAttributeName value:newFont range:range];
    }
}];
self.attributedText = [mutableString copy];

我注意到在中运行此代码时循环检查sizeThatFits以了解文本何时足够小以适应我在某些情况下会发生比赛为零。对于任何小于我开始的字体值,高度计算为60px,恰好是50px。

I noticed that while running this code in a while loop checking sizeThatFits to know when the text is small enough to fit that I would have a race to zero occur in some circumstances. The height is being calculated as 60px for any font value smaller than what I started with, which happens to be 50px.

NSLog 使用NSAttributedString我发现有几个属性我没有添加密钥 NSOriginalFont ,它似乎不在支持的属性列表中此处。 NSOriginalFont发生了什么?为什么我的大小计算不正确?

When NSLoging the NSAttributedString I find that there are several attributes that I did not add with the key NSOriginalFont which does not appear to be in the list of supported attributes here. What's going on with NSOriginalFont? Why is my size being calculated incorrectly?

推荐答案

我最终解决了这个问题,但发现网上缺乏关于它的信息,所以我决定在这里记录我的解决方案。

I ended up fixing this but found a lack of information on the web about it, so I decided to document my solution here.

NSOriginalFont 当使用的字体不支持时,会创建属性或者字符串中的更多字符。 NSAttributedString添加了这些属性,这些属性跟踪在替换为Helvetica之前假定的字体。我可以编造一个有用的情况(你有时会运行大写字符串的全部字体:on?)但它对我没用。

NSOriginalFont attributes are created when the font used doesn't support one or more characters in the string. NSAttributedString adds these attributes that track what the font was "supposed" to be before a substitution to Helvetica occurred. I could make up a situation where this is useful (an all-caps font that you sometimes run uppercaseString: on?) but it wasn't useful to me.

In事实上这是有害的。当我迭代我的字体相关属性以减小大小时,如上所示,文本的可见大小正在减少,但NSOriginalFont属性保留了对大尺寸的引用。

In fact it was harmful. As I iterated through my font related attributes to decrease the size as shown above the visible size of the text was decreasing but the NSOriginalFont attribute retained a reference to the large size.

NSOriginalFont没有内置常量,但如果按名称调用它,则可以从NSMutableAttributedString中删除它。如果你这样做,你将开始从sizeThatFits,boundingRectWithSize和其他类似的函数得到正确的结果,假设你传递了正确的选项。

There's no built in constant for NSOriginalFont but if you call it by name it's possible to strip it from your NSMutableAttributedString. If you do you'll begin to get proper results from sizeThatFits, boundingRectWithSize, and other similar functions assuming that you're passing the correct options.

我最终创建了一个下面包含NSMutableAttributedString的简单类别方法,效果很好。

I ended up creating a simple category method on NSMutableAttributedString, included below, that works well.

NSMutableAttributedString + StripOriginalFont.h

@interface NSMutableAttributedString (StripOriginalFont)

- (void) stripOriginalFont;

@end

NSMutableAttributedString + StripOriginalFont.m

@implementation NSMutableAttributedString (StripOriginalFont)

- (void) stripOriginalFont{
    [self enumerateAttribute:@"NSOriginalFont" inRange:NSMakeRange(0, self.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
        if (value){
            [self removeAttribute:@"NSOriginalFont" range:range];
        }
    }];
}

@end

大概你可以简单地修改它保持它同步而不是完全删除它,但这对我这个特定项目没有用。

Presumably you could simply modify it to keep it "in-sync" instead of removing it entirely but it wasn't useful to me for this particular project.

这篇关于NSAttributedString报告UITextView sizeThatFits和boundingRectWithSize的大小不正确,并设置了正确的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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