对于 a UILabel
,我想找出从触摸事件接收到的特定点的字符索引。我想使用 Text Kit 为 iOS 7 解决这个问题。
由于 UILabel 不提供对其的访问NSLayoutManager
,因此我根据UILabel
' 的配置创建了自己的,如下所示:
- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint location = [recognizer locationInView:self];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.bounds.size];
[layoutManager addTextContainer:textContainer];
textContainer.maximumNumberOfLines = self.numberOfLines;
textContainer.lineBreakMode = self.lineBreakMode;
NSUInteger characterIndex = [layoutManager characterIndexForPoint:location
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
if (characterIndex < textStorage.length) {
NSRange range = NSMakeRange(characterIndex, 1);
NSString *value = [self.text substringWithRange:range];
NSLog(@"%@, %zd, %zd", value, range.location, range.length);
}
}
}
上面的代码在一个配置为调用( GistUILabel
) 的子类中。UITapGestureRecognizer
textTapped:
生成的字符索引是有意义的(从左到右点击时会增加),但不正确(最后一个字符大约在标签宽度的一半处到达)。看起来可能是字体大小或文本容器大小配置不正确,但找不到问题。
我真的很想让我的班级成为一个子类,UILabel
而不是使用UITextView
. 有没有人解决这个问题UILabel
?
更新:我在这个问题上花了一张 DTS 票,Apple 工程师建议使用我自己的布局管理器的实现来覆盖UILabel
's drawTextInRect:
,类似于以下代码片段:
- (void)drawTextInRect:(CGRect)rect
{
[yourLayoutManager drawGlyphsForGlyphRange:NSMakeRange(0, yourTextStorage.length) atPoint:CGPointMake(0, 0)];
}
我认为让我自己的布局管理器与标签的设置保持同步需要做很多工作,所以UITextView
尽管我更喜欢UILabel
.
更新2:UITextView
毕竟我决定使用。所有这些的目的是检测对嵌入文本的链接的点击。我尝试使用NSLinkAttributeName
,但快速点击链接时此设置未触发委托回调。取而代之的是,您必须按下链接一段时间——这很烦人。所以我创建了没有这个问题的CCHLinkTextView 。