我有一个NSAttributedString报告一个boundingRectWithSize(并且扩展名为UITextView,它不正确地计算它的sizeThatFits)当字体大小从用于创建它的字体大小减少时。
在我执行类似操作的所有NSAttributedStrings上都没有发生,所以这里是重现的步骤。
从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
NSAttributedString时,我发现有几个属性我没有使用密钥NSOriginalFont
添加,而这些属性似乎不在支持的属性列表here中。 NSOriginalFont发生了什么?为什么我的尺寸计算不正确?
答案 0 :(得分:12)
我最终解决了这个问题,但发现网上缺乏关于它的信息,所以我决定在这里记录我的解决方案。
当使用的字体不支持字符串中的一个或多个字符时,将创建 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, NSRange range, BOOL *stop) {
if (value){
[self removeAttribute:@"NSOriginalFont" range:range];
}
}];
}
@end
据推测,您可以简单地修改它以使其“同步”而不是完全删除它,但这对我来说对这个特定项目没用。
答案 1 :(得分:1)
不知道这是否有助于解决您的问题,但请查看我的解决方案,以便在此处自动调整文本UITextView:https://stackoverflow.com/a/30400391/1664123
答案 2 :(得分:1)
使用attributedString创建NSTextStorage对象和init。 并计算边界。
NSTextStorage *attributedText = [[NSTextStorage alloc] initWithAttributedString:[[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName:systemFont}]];
CGRect textRect = [attributedText boundingRectWithSize:CGSizeMake(textW, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
答案 3 :(得分:0)
要快速剥离,可以使用以下扩展名:
extension NSAttributedString {
func strippedOriginalFont() -> NSAttributedString? {
let mutableCopy = self.mutableCopy() as? NSMutableAttributedString
mutableCopy?.removeAttribute(NSAttributedStringKey(rawValue: "NSOriginalFont"), range: NSMakeRange(0, self.length))
return mutableCopy?.copy() as? NSAttributedString
}
}