在UILabel / UITextView中触及单词

时间:2012-01-10 23:10:08

标签: ios text word touch uilabel

我想要做的是创建一个文本容器组件,该组件能够指示当触摸它时最接近的单词(即触摸点“后面”这个词)。

首先,我创建了一个UILabel子类并覆盖了touchesEnded:withEvent:方法来确定触摸的CGPoint。我还编写了一个方法,使用sizeWithFont:forWidth:lineBreakMode:计算文本中每个单词的相应“框架”(CGRect)。通过触摸的CGPoint和此帧,我可以确定实际触摸的是哪个单词。但是计算帧的方法仅适用于单行文本。

所以现在我需要知道文本的哪一部分在给定的行上(即文本是如何被分割的),这样我就可以计算出每个单词的正确左边距和上边距。

知道如何获得这个吗? 或者也许有一个更简单的解决方案来实现这一目标? This post was unfortunately not very helpful... ...

3 个答案:

答案 0 :(得分:9)

(链接帖子中有一个示例代码项目的链接,其中包含一些有用的示例代码,但我也将在此概述您的流程。)

简而言之,您将需要使用Core Text,这是Apple的高级基于C的文本处理框架,支持iOS和OS X中所有复杂的文本布局。

完整的代码将涉及到一些问题,但您想要了解的关键方法是:

CTFramesetterCreateWithAttributedString() - 将此项与您从标签文本中获取的NSAttributedString结合使用,以创建框架集

CTFramesetterCreateFrame() - 使用此方法从上面的framesetter获取文本的CTFrameRef。您需要使用标签边界创建CGPathRef才能执行此操作。

CTFrameGetLines(),CTFrameGetLineOrigins() - 使用它们分别获取与排版行对应的CTLineRefs和行原点的坐标,然后使用CTLineGetStringIndexForPosition()在触摸位置查找字符索引。

然后,您可以使用此字符索引(在行的参考框架中)向后工作,并在完整字符串中查找实际的字符/单词/等。

不要忘记,问题很复杂:

  1. 如果您使用UILabel的原生绘图,则必须注意与排版指标完美匹配,这可能很麻烦,因为大多数对象(例如CTFontRef)与其UIKit对应物没有免费桥接。有时,实现自己的绘图可能更容易,这将保证度量匹配。

  2. Core Text使用相对于普通iOS绘图系统的倒置坐标系。如果你得到了古怪的结果,特别是如果你自己绘图,这是值得一看的。

  3. 这不是世界上最容易的任务,但远非不可能。祝你好运!

答案 1 :(得分:5)

搜索了一下后,我为此编写了代码。代码适用于UITextViewUILabel
只需下载VSWordDetector.zip然后解压缩并拖动&将文件夹VSWordDetector放入项目中。
有两个文件VSWordDetector.hVSWordDetector.m#import VSWordDetector.h课程中ViewController

@property (strong, nonatomic) VSWordDetector *wordDetector;

注意:不要将其属性设置为本地。

现在已经为您准备好了,只需将其添加到textViewsLabels

即可
-(void)viewDidLoad
{
   self.wordDetector = [[VSWordDetector alloc] initWithDelegate:self];
   [self.wordDetector addOnView:textView];
   [self.wordDetector addOnView:label];
}

-(void)wordDetector:(VSWordDetector *)wordDetector detectWord:(NSString *)word
{
   NSLog(@"Detected Word: %@", word);
}

当您点按已连接的标签或textView时,系统会调用此委托方法。

对于 VSWordDetector

编辑 Sample Code

建议编辑:如果您不想在此处下载示例代码,请输入两个文件的代码。请参阅此gist文件VSWordDetector

答案 2 :(得分:2)

虽然这是一个老问题,但我认为这可能会有所帮助。

由于学习核心文本很大,我选择了GLTapDemo by German Laullon

通过一些更改,这非常适合检测UILabel上的触摸词。