对于给定的NSRange,我希望在UILabel中找到与这NSRange的字形相对应的CGRect.例如,我想找出在句子"敏捷的棕色狐狸跳过懒狗"中包含"狗"这个词的CGRect.

问题的可视描述

诀窍是,UILabel有多行,而文本实际上是attributedText,所以要找到字符串的确切位置有点困难.

我想要在我的UILabel子类上编写的方法如下所示:

 - (CGRect)rectForSubstringWithRange:(NSRange)range;

Details, for those who are interested:

我的目标是能够达到create a new UILabel with the exact appearance and position of the UILabel, that I can then animate.我已经搞定了剩下的部分,但正是这一步阻碍了我.

What I've done to try and solve the issue so far:

  • 我曾希望在iOS7中会有一些Text Kit来解决这个问题,但是我看到的大多数Text Kit的例子都集中在UITextViewUITextField上,而不是UILabel.
  • 我在这里看到了另一个关于Stack Overflow的问题,它promise 解决这个问题,但公认的答案已经有两年多了,而且代码在处理属性文本时执行得不好.

I'd bet that the right answer to this involves one of the following:

  • 使用标准文本工具包方法在一行代码中解决此问题.我打赌会涉及NSLayoutManagertextContainerForGlyphAtIndex:effectiveRange
  • 编写一个复杂的方法,将UILabel分解成行,并查找行中字形的RET,可能使用Core Text方法.我目前最好的 Select 是拆解@mattt's个优秀的TTTAttributedLabel,它有一个方法可以在某个点处找到一个字形--如果我反转一下,找到一个字形的点,可能会行得通.

更新:这里有一个github要点,其中包括我迄今为止试图解决这个问题的三件事:https://gist.github.com/bryanjclark/7036101

推荐答案

根据Joshua's answer的代码,我想出了以下似乎很有效的方法:

- (CGRect)boundingRectForCharacterRange:(NSRange)range
{
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:[self attributedText]];
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
    [textStorage addLayoutManager:layoutManager];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:[self bounds].size];
    textContainer.lineFragmentPadding = 0;
    [layoutManager addTextContainer:textContainer];

    NSRange glyphRange;

    // Convert the range for glyphs.
    [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];

    return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];
}

Ios相关问答推荐

如何创建自定义组件来接受(和传递)所有可能的Textfield参数?

为什么导航栏在与Style.Page的选项卡栏一起使用时停止工作?

无法添加以供审阅-Xcode 15.0.1

多协议和类继承混乱,Swift

不可发送类型 '[String : Any]?'在调用非隔离实例方法 XXX 时退出主参与者隔离上下文不能跨越参与者边界

ITMS-90432:将应用上传到应用store 时出现问题

Flutter动画放大图

发生异常:需要 issuerId

SwiftUI Select 器值在超过最大值时重置

如何在Collection 后更改并保留按钮 colored颜色 ,然后在 SwiftUI 中切换回来?

从视图模型中更新 EnvironmentObject

我可以使用同一个 Firebase 应用将多个 Flutter 应用添加到一个 Firebase 数据库吗?

按钮在 SwiftUI 中没有采用给定的高度和宽度

在 UICollectionView 上动态设置布局导致莫名其妙的 contentOffset 变化

如何在 Xcode 4 中切换 .h 和 .m

如何从一个特定的视图控制器中隐藏导航栏

界面生成器中 UIView 的边框 colored颜色 不起作用?

如何判断是否为 64 位构建了静态库?

如何在 Objective-C (iOS) 中的图像上写文本?

如何使用 presentModalViewController 创建透明视图