ios - NSAttributedString 报告 UITextView sizeThatFits 和 boundingRectWithSize 的大小不正确,并设置了正确的选项

标签 ios objective-c ios7 fonts textkit

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

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

  1. 使用不包含完整 unicode 字符集的非标准字体。
  2. 确保字符串包含此“不受支持”集中的字符。 iOS 会将它们呈现为适当大小的 Helvetica。
  3. 缩小 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 之前“应该”是什么。我可以编造一个有用的情况(你有时运行 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/

相关文章:

ios - 如何以每秒240帧的速度录制和保存?

ios - 如何添加 NSMutableArray 的总和

iphone - UITableViewCell 背景颜色与 alpha 不同的行为

ios - Swift WatchConnectivity 应用程序上下文作为字典

javascript - 使用 HTML5/javascript 校正音频音量输出分贝,关闭预处理

objective-c - XCode 4.5中的工作区/编译/库问题,试图集成Box2DCocos2DExamples.xcodeproj文件

ios - 如何修改 PKRevealController 滑出式菜单以应对 iOS 7?

ios - UISearchDisplayController 搜索栏重叠导航栏并自行调整大小 IOS 7

ios - 如果日历访问被拒绝,则显示警报 Swift 3

ios - 如何从 plist 文件中只加载选定的数据