在我执行类似操作的所有NSAttributedStrings上都不会发生这种情况,因此这里是重现的步骤.
>使用不包含完整unicode字符集的非标准字体.
>确保字符串包含此“不支持”集中的字符. iOS会将它们渲染为适当大小的Helvetica.
>在NSAttributedString中的所有字体属性上缩放字体.我这样做的代码产生了这个问题.
从UITextView子类内部:
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];
我注意到,在while循环中运行此代码时,检查sizeThatFits以了解文本何时足够小以适应,我会在某些情况下出现争用零.对于任何小于我开始时的字体值,高度计算为60px,恰好是50px.
当NSLoging NSAttributedString时,我发现有几个属性我没有添加密钥NSOriginalFont,它似乎不在支持的属性列表here中.NSOriginalFont发生了什么?为什么我的尺寸计算不正确?
解决方法
当使用的字体不支持字符串中的一个或多个字符时,将创建NSOriginalFont属性. NSAttributedString添加了这些属性,这些属性跟踪在替换为Helvetica之前“假定”的字体.我可以编造一个有用的情况(你有时会运行大写字符串的全部字体:on?)但它对我没用.
事实上它是有害的.当我迭代我的字体相关属性以减小如上所示的大小时,文本的可见大小正在减小,但NSOriginalFont属性保留了对大尺寸的引用.
NSOriginalFont没有内置常量,但如果按名称调用它,则可以从NSMutableAttributedString中删除它.如果你这样做,你将开始从sizeThatFits,boundingRectWithSize和其他类似的函数得到正确的结果,假设你传递了正确的选项.
我最终在NSMutableAttributedString上创建了一个简单的类别方法,包含在下面,效果很好.
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,BOOL *stop) { if (value){ [self removeAttribute:@"NSOriginalFont" range:range]; } }]; } @end