gpt4 book ai didi

objective-c - UILabel 触摸点的字符索引

转载 作者:太空狗 更新时间:2023-10-30 03:11:47 27 4
gpt4 key购买 nike

对于 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);
}
}
}

上面的代码在 UILabel 子类中,带有配置为调用 textTapped: ( Gist ) 的 UITapGestureRecognizer

生成的字符索引有意义(从左向右点击时增加),但不正确(最后一个字符大约达到标签宽度的一半)。看起来可能是字体大小或文本容器大小配置不正确,但找不到问题。

我真的很想让我的类成为 UILabel 的子类,而不是使用 UITextView。有没有人为 UILabel 解决了这个问题?

更新:我在这个问题上花了一张 DTS 票,Apple 工程师建议用一个实现覆盖 UILabeldrawTextInRect:使用我自己的布局管理器,类似于此代码片段:

- (void)drawTextInRect:(CGRect)rect 
{
[yourLayoutManager drawGlyphsForGlyphRange:NSMakeRange(0, yourTextStorage.length) atPoint:CGPointMake(0, 0)];
}

我认为让我自己的布局管理器与标签的设置保持同步需要做很多工作,所以我可能会使用 UITextView 尽管我更喜欢 UILabel.

更新 2:毕竟我决定使用 UITextView。所有这一切的目的是检测对文本中嵌入的链接的点击。我尝试使用 NSLinkAttributeName,但此设置在快速点击链接时不会触发委托(delegate)回调。取而代之的是,你必须按链接一段时间——这很烦人。所以我创建了CCHLinkTextView没有这个问题。

最佳答案

我试过 Alexey Ishkov 的解决方案。最后我得到了解决方案!在您的 UITapGestureRecognizer 选择器中使用此代码片段:

UILabel *textLabel = (UILabel *)recognizer.view;
CGPoint tapLocation = [recognizer locationInView:textLabel];

// init text storage
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:textLabel.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];

// init text container
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(textLabel.frame.size.width, textLabel.frame.size.height+100) ];
textContainer.lineFragmentPadding = 0;
textContainer.maximumNumberOfLines = textLabel.numberOfLines;
textContainer.lineBreakMode = textLabel.lineBreakMode;

[layoutManager addTextContainer:textContainer];

NSUInteger characterIndex = [layoutManager characterIndexForPoint:tapLocation
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];

希望这会帮助一些人!

关于objective-c - UILabel 触摸点的字符索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21349725/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com