NSAttributedString 报告 UITextView sizeThatFits 和boundingRectWithSize 的尺寸不正确,并设置了正确的选项

2023-11-27

我有一个 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 以了解文本何时足够小以适合在某些情况下发生零竞争的情况。对于任何比我开始时更小的字体值(恰好是 50px),高度被计算为 60px。

When 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

想必您可以简单地修改它以使其保持“同步”,而不是完全删除它,但它对我这个特定项目没有用处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSAttributedString 报告 UITextView sizeThatFits 和boundingRectWithSize 的尺寸不正确,并设置了正确的选项 的相关文章

  • 是否可以自定义区域形状?核心位置

    例如 至少我想要一个正方形 矩形 道路的形状作为我的区域 不它不是 根据文档 目前唯一的区域类是 CLCircularRegion 显然是圆形 和 CLBeaconRegion 基于与 iBeacon 的接近度 未来苹果可能会添加对自定义形
  • 自动布局中的“使用标准值”和“限制边距”是什么意思?

    我已经完成了一些自动布局教程 例如this https developer apple com library ios recipes xcode help IB auto layout chapters pin constraints h
  • 使用 arrayWithCapacity 有什么好处

    arrayWithCapacity是一个定义在NSArray h并实施于NSArray m 当我查看代码时GNUStep https raw githubusercontent com gnustep gnustep base master
  • iOS 中特定字符串的 SHA1

    根据我的要求 输入字符串必须转换为字节值 string 的每个字符都是 16 位值 必须转换为低 8 位 然后在字节数组上计算 Sha1 生成的 SHA 1 将转换为 40 个字符的字符串 我知道如何将字符串转换为 SHA1 但其余部分对我
  • 使用 Swift 的核心数据瞬态值

    有谁知道 或者有一个例子 如何使用 Swift 处理核心数据瞬态值 我知道在属性之前使用 NSManaged 但无法弄清楚如何编写逻辑以使用 Swift 构建瞬态值 复选标记短暂的数据模型中特定属性的字段 例如sectionTitle 为该
  • iOS7状态栏和导航栏问题

    我正在将我的应用程序迁移到 iOS 7 为了处理状态栏问题 我添加了以下代码 if UIDevice currentDevice systemVersion floatValue gt 7 0f CGRect frame self navi
  • iOS表单键盘不消失

    我知道我必须打电话 BOOL disablesAutomaticKeyboardDismissal return NO this dismiss keyboard on ios BOOL textViewShouldBeginEditing
  • iOS:AVPlayer 视频预加载

    我正在使用 AVPlayer 来播放视频 它们的长度很短 2 5秒 它们以随机顺序播放 问题是 当更改视频并开始播放新视频时 设备会滞后很短的时间 但我不希望更改流畅 有没有办法用 AVPlayer 预加载视频 尝试使用AVQueuePla
  • AVVideoComposition 应用过滤器处理程序不调用

    I want to add an overlay image into a video I use AVVideoComposition and CIFilter to do this but AVAsynchronousCIImageFi
  • OCMockito everything() 用于原始类型

    对于方法签名 void insertValue NSUInteger value 我想看看是否有任何值的 insertValue 永远不会被调用 verifyCount test never insertValue 0 由于编译器抱怨 ev
  • 如何使用最新的 FBSDK 在 iOS 应用程序中集成 Facebook,而不重定向 Safari 浏览器

    您好 我正在搜索避免新的 facebooksdk 重定向到 safari 的答案 如何在应用程序内打开 facebook 登录视图 如果它重定向到 safari 可能会在应用程序商店中拒绝 帮助我 提前致谢 昨天我使用以下方式提交我的应用程
  • 导航栏的横向视图问题

    默认导航栏高度为 64 但更改后 其横向导航栏高度的方向更改为 28 我想设置修复所有方向的导航栏大小 您可以添加方向观察者 NotificationCenter default addObserver self selector sele
  • 从 NSArray 为 UITableView 创建索引

    我读过创建索引 uitableview 旁边的 a z 的最佳方法是设置一个 nsdictionaries 数组 其中每个字典对应一个部分 并且 rowValue 键包含一个行数组 NSDictionary headerTitle gt A
  • iOS 如何以编程方式简单返回到先前呈现/推送的视图控制器?

    如何以编程方式返回到先前的视图控制器 我找到了这个answer https stackoverflow com questions 28760541 programmatically go back to previous viewcont
  • HTML5 Safari iOS 仅访问相机而不访问照片库

  • iOS 10 bug:UICollectionView 收到索引路径不存在的单元格的布局属性

    在 iOS 10 设备上运行我的应用程序时出现以下错误 UICollectionView 收到索引路径不存在的单元格的布局属性 在 iOS 8 和 9 中工作正常 我一直在研究 发现这与使集合视图布局无效有关 我尝试实施该解决方案但没有成功
  • 为什么 NSOrderedSet 不继承 NSSet?

    当然 有序集是集合的更具体的情况 那么为什么NSOrderedSet继承自NSObject而不是NSSet 我通过了界面NSSet你是对的 有序集似乎满足里氏替换原则 http en wikipedia org wiki Liskov su
  • 获取 PHAsset 的本地文件路径

    我希望我的用户能够在 Instagram 上分享一张照片 并且我需要获取该照片的本地文件目录 不过 我将图像作为 PHAsset 获取 而不是 ALAsset 所有其他答案似乎都涵盖了这个主题 查看 PHAsset 文档 我没有看到 本地目
  • 获取选定行 NSTableView 的值

    我如何获取 NSTableView 中选定行的值 通过使用selectedRow see here https developer apple com documentation appkit nstableview 1535010 sel
  • 迭代 NSDictionary 时保持顺序

    我有一个 NSDictionary 它正在迭代并将数据保存到核心数据 如下所示 NSDictionary details valueDict objectForKey shipment master for NSDictionary res

随机推荐