我有一个 NSAttributedString,当字体大小从用于创建它的字体大小减小时,它报告一个 boundingRectWithSize(并且扩展为一个 UITextView,它不正确地计算它的 sizeThatFits)。
它不会发生在我执行类似操作的所有 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。
当 NSLog
ing NSAttributedString 时,我发现有几个属性我没有使用键 NSOriginalFont
添加,它们似乎不在支持的属性列表中here . NSOriginalFont 是怎么回事?为什么我的尺寸计算不正确?
最佳答案
我最终解决了这个问题,但发现网络上缺乏相关信息,所以我决定在此处记录我的解决方案。
NSOriginalFont
属性在使用的字体不支持字符串中的一个或多个字符时创建。 NSAttributedString 添加了这些属性来跟踪字体在替换为 Helvetica 之前“应该”是什么。我可以编造一个有用的情况(你有时运行 uppercaseString: 的全大写字体?)但它对我没有用。
事实上它是有害的。当我遍历我的字体相关属性以减小尺寸时,如上所示,文本的可见尺寸正在减小,但 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, NSRange range, BOOL *stop) {
if (value){
[self removeAttribute:@"NSOriginalFont" range:range];
}
}];
}
@end
大概您可以简单地修改它以使其保持“同步”而不是完全删除它,但它对我这个特定项目没有用。
关于ios - NSAttributedString 报告 UITextView sizeThatFits 和 boundingRectWithSize 的大小不正确,并设置了正确的选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22826943/