我有一个文本,它在屏幕上显示如下:
#first SomePersonFirstName
SomePersonLastName #secondTag
在我的应用程序中,我保留了有关此文本的3个标签及其范围的信息,其中包括:
现在我将它显示给用户之后我想要检测哪一个被点击了,所以我遍历所有的信息,为每个信息获取boundingRectForGlyphRange
,并检查这个矩形是否包含一个点点击了。
一切都在运作,但是我遇到了一个奇怪的情况,这让我对如何做到了这一点。 问题是这些标签的边界反应重叠。
因为person标签被分成2行,所以绑定的rects从0,0开始并覆盖#first bounding rect。
问题是当你点击这个冲突区域时,无法确定哪一个被点击了。
我实际上不知道如何处理。有没有其他方法来检测边界矩形,但实际上不会绑定到空白区域,这只会覆盖文本本身?
修改
我正在使用的代码:
- (CGRect)boundingRectForCharacterRange:(NSRange)range
{
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self.labelTitle.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(self.labelTitle.bounds.size.width, CGFLOAT_MAX)];
textContainer.lineFragmentPadding = 0;
textContainer.lineBreakMode = self.labelTitle.lineBreakMode;
[layoutManager addTextContainer:textContainer];
NSRange glyphRange;
[layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];
return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];
}
-(void)tapped:(UIGestureRecognizer *)recognizer
{
UILabel *label = (UILabel *)recognizer.view;
CGPoint location = [recognizer locationInView:label];
CommentTag* selectedCommentTag = nil;
for (CommentTag* commentTag in self.comment.tags)
{
CGRect commentRect = [self boundingRectForCharacterRange:[commentTag tagRange]];
if(CGRectContainsPoint(commentRect, location))
{
if(selectedCommentTag == nil)
{
selectedCommentTag = commentTag;
}
else
{
if(selectedCommentTag.offset > commentTag.offset)
{
selectedCommentTag = commentTag;
}
}
}
}
if(selectedCommentTag)
{
if([selectedCommentTag.type isEqualToString:COMMENTTAG_TYPE_TAG])
{
NSLog(@"%@", [selectedCommentTag value]);
}
}
}
这里我只是将第一个标签放在左边,但这并没有解决我的例子中#secondTag的问题
答案 0 :(得分:2)
当两个边界反复重叠时,有两(3)个实例:
对于(1),当您接受点击普通字形时,您只需要制定自己的一套规则。
对于(2),总是更喜欢只跨越一条线的范围 - 你可以通过比较矩形高度来判断。
对于(3),你必须遍历这些行。
或者,您是否考虑过相反的方法?
NSRange characterRange = [layoutManager glyphRangeForBoundingRect:CGRectMake(point.x, point.y, 1, 1) inTextContainer:container];
if (NSLocationInRange(characterRange.location, firstRange) {
// ...
} else if (NSLocationInRange(characterRange.location, secondRange) {
// ...
} // etc...
通过将您的触摸点转换为尺寸为CGRect
的{{1}},您可以让1x1
为您提供layoutManager
长度{{} 1}}表示触摸点处的单个字形。使用此NSRange
1
,您可以与NSRange
列表进行比较,看看您点击了哪一个。使用你的来源:
location